itom 1.0.14
D:/git-itom/sources/itom/DataObject/dataobj.h
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 
00048 #include "readWriteLock.h"
00049 
00050 #include <vector>
00051 #include <map>
00052 #include <string>
00053 
00054 namespace cv {
00055 
00056    template<> inline ito::float32 saturate_cast<ito::float32>( ito::float64 v)
00057    {
00058        //return (float32)v;
00059        if(cvIsInf(v)) return std::numeric_limits<ito::float32>::infinity();
00060        if(cvIsNaN(v)) return std::numeric_limits<ito::float32>::signaling_NaN();
00061        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() )));
00062    }
00063 
00064    template<> inline ito::float64 saturate_cast<ito::float64>( ito::float32 v)
00065    {
00066        //return (float64)v;
00067        if(cvIsInf(v)) return std::numeric_limits<ito::float64>::infinity();
00068        if(cvIsNaN(v)) return std::numeric_limits<ito::float64>::signaling_NaN();
00069        return static_cast<ito::float64>(v);
00070    }
00071 
00072    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; }
00073    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; }
00074 
00075    template<> inline ito::complex64 saturate_cast(ito::uint8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00076    template<> inline ito::complex64 saturate_cast(ito::int8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00077    template<> inline ito::complex64 saturate_cast(ito::uint16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00078    template<> inline ito::complex64 saturate_cast(ito::int16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00079    template<> inline ito::complex64 saturate_cast(ito::uint32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00080    template<> inline ito::complex64 saturate_cast(ito::int32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00081    template<> inline ito::complex64 saturate_cast(ito::float32 v){ return ito::complex64(v,0.0); }
00082    template<> inline ito::complex64 saturate_cast(ito::float64 v){ return ito::complex64(saturate_cast<ito::float32>(v),0.0); }
00083    template<> inline ito::complex64 saturate_cast(ito::complex64 v){ return v; }
00084    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())); }
00085 
00086    template<> inline ito::complex128 saturate_cast(ito::uint8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00087    template<> inline ito::complex128 saturate_cast(ito::int8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00088    template<> inline ito::complex128 saturate_cast(ito::uint16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00089    template<> inline ito::complex128 saturate_cast(ito::int16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00090    template<> inline ito::complex128 saturate_cast(ito::uint32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00091    template<> inline ito::complex128 saturate_cast(ito::int32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00092    template<> inline ito::complex128 saturate_cast(ito::float32 v){ return ito::complex128(saturate_cast<ito::float64>(v),0.0); }
00093    template<> inline ito::complex128 saturate_cast(ito::float64 v){ return ito::complex128(v,0.0); }
00094    template<> inline ito::complex128 saturate_cast(ito::complex64 v){ return ito::complex128(saturate_cast<ito::float64>(v.real()),saturate_cast<ito::float64>(v.imag())); }
00095    template<> inline ito::complex128 saturate_cast(ito::complex128 v){ return v; }
00096 
00097 } // namespace cv
00098 
00099 
00100 namespace ito {
00101 
00102 #define __ITODEBUG 1
00103 
00104 class DObjIterator;  // Forward declaration
00105 class DataObject;
00106 class Range;
00107 struct Scalar;
00108 class DataObjectTags;
00109 class DataObjectTagType;
00110 
00111 //----------------------------------------------------------------------------------------------------------------------------------
00116 class Range
00117 {
00118     public:
00119         Range() : start(0), end(0) {}                           
00120         Range(int _start, int _end) { _start < _end ? (end = _end, start = _start) : (start = _end, end = _start); }  
00121         inline unsigned int size() const { return end - start; }
00122         inline bool empty() const { return (start == end); }    
00123         static Range all() { return Range(INT_MIN, INT_MAX); }  
00125         int start;                                               
00126         int end;                                                 
00127 };
00128 
00129 //----------------------------------------------------------------------------------------------------------------------------------
00130 class DataObjectTagType
00131 {
00132     private:
00133         double m_dVal;
00134         std::string m_strValue;
00135         int m_type;        
00136 
00137     public:
00139         DataObjectTagType() : m_dVal(0), m_strValue(""), m_type(DataObjectTagType::typeInvalid){};
00140         DataObjectTagType(double dVal) : m_dVal(dVal), m_strValue(""), m_type(DataObjectTagType::typeDouble){};
00141         DataObjectTagType(std::string strVal) : m_dVal(std::numeric_limits<double>::signaling_NaN()), m_strValue(strVal), m_type(DataObjectTagType::typeString){};
00142         DataObjectTagType(const char* cVal) : m_dVal(std::numeric_limits<double>::signaling_NaN()), m_type(DataObjectTagType::typeString){ cVal == NULL ?  m_strValue = "" : m_strValue = cVal;};
00144         DataObjectTagType(const DataObjectTagType& copyConstr) : m_dVal(copyConstr.m_dVal), m_strValue(copyConstr.m_strValue), m_type(copyConstr.m_type){};
00145 
00146         DataObjectTagType & operator = (const DataObjectTagType rhs)
00147         {
00148             this->m_dVal = rhs.m_dVal;
00149             this->m_strValue = rhs.m_strValue;
00150             this->m_type = rhs.m_type;
00151 
00152             return *this;
00153         }
00154 
00155         enum tTagType
00156         {
00157             typeInvalid     = 0x000000,
00158             typeDouble      = 0x000008,
00159             typeString      = 0x000020
00160         };
00161 
00162         inline int getType(void) const {return m_type;};
00163         inline bool isValid(void) const { return (m_type == DataObjectTagType::typeInvalid) ? false: true;};
00164 
00170         inline double getVal_ToDouble(void)
00171         {
00172             if(m_type == DataObjectTagType::typeInvalid)
00173             {
00174                 return std::numeric_limits<double>::signaling_NaN();
00175             }
00176             else if(m_type == DataObjectTagType::typeDouble)
00177             {
00178                 return m_dVal;
00179             }
00180             else
00181             {
00182                 double dVal = std::numeric_limits<double>::signaling_NaN();
00183                 //dVal = atof(m_strValue.c_str()); //sometimes the result of that line has been arbitrary, therefore this conversion should fail.
00184                 return dVal;
00185             }
00186         }
00187 
00193         inline std::string getVal_ToString(void)
00194         {
00195             if(m_type == DataObjectTagType::typeInvalid)
00196             {
00197                 return std::string();
00198             }
00199             else if(m_type == DataObjectTagType::typeString)
00200             {
00201                 return m_strValue;
00202             }
00203             else
00204             {
00205                                 if(cvIsNaN(m_dVal)) return std::string("NaN");
00206                                 if(cvIsInf(m_dVal)) return std::string("Inf");
00207                 /*if(m_dVal == std::numeric_limits<double>::quiet_NaN()) return std::string("NaN");
00208                 if(m_dVal == std::numeric_limits<double>::signaling_NaN()) return std::string("NaN");
00209                 if(m_dVal == std::numeric_limits<double>::infinity()) return std::string("Inf");*/
00210 
00211                 std::ostringstream strs;
00212                 strs << m_dVal;
00213 
00214                 return strs.str();
00215             }
00216         }
00217 };
00218 
00219 //----------------------------------------------------------------------------------------------------------------------------------
00228 class DataObjectTags
00229 {
00230 private:
00231     //std::map<std::string,std::string> m_tags;   /*!< map for tags with keyword (std::string) and value (std::string) */
00232     std::map<std::string, DataObjectTagType> m_tags;   
00234     std::vector<double> m_axisOffsets;          
00235     std::vector<double> m_axisScales;           
00236     std::vector<std::string> m_axisDescription; 
00237     std::vector<std::string> m_axisUnit;        
00238     double m_valueOffset;                       
00239     double m_valueScale;                        
00240     std::string m_valueDescription;             
00241     std::string m_valueUnit;                    
00243     double m_rotMatrix[9];                      
00245     friend class DataObject;
00246 
00247 
00248 public:
00250     DataObjectTags(unsigned int totalAxisNum) : m_valueOffset(0.0), m_valueScale(1.0), m_valueDescription(""), m_valueUnit("")
00251     {
00252         m_tags.clear();
00253         m_axisOffsets.resize(totalAxisNum, 0.0);
00254         m_axisScales.resize(totalAxisNum, 1.0);
00255         m_axisDescription.resize(totalAxisNum, "");
00256         m_axisUnit.resize(totalAxisNum, "");
00257         m_valueUnit = std::string();
00258         memset(m_rotMatrix, 0, sizeof(double)*9);
00259         m_rotMatrix[0] = 1; // r11
00260         m_rotMatrix[4] = 1; // r22
00261         m_rotMatrix[8] = 1; // r33
00262     }
00263 
00265     ~DataObjectTags()
00266     {
00267         m_tags.clear();
00268         m_axisOffsets.clear();
00269         m_axisScales.clear();
00270         m_axisDescription.clear();
00271         m_axisUnit.clear();
00272     }
00273 
00275     DataObjectTags(const DataObjectTags& copyConstr)
00276     {
00277         m_tags = copyConstr.m_tags;
00278         m_axisOffsets = copyConstr.m_axisOffsets;
00279         m_axisScales = copyConstr.m_axisScales;
00280         m_axisDescription = copyConstr.m_axisDescription;
00281         m_axisUnit = copyConstr.m_axisUnit;
00282         m_valueOffset = copyConstr.m_valueOffset;
00283         m_valueScale = copyConstr.m_valueScale;
00284         m_valueDescription = copyConstr.m_valueDescription;
00285         m_valueUnit = copyConstr.m_valueUnit;
00286         memcpy(m_rotMatrix,copyConstr.m_rotMatrix, sizeof(double)*9);
00287     }
00288 
00289     //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.)
00290 
00291 };
00292 
00293 //----------------------------------------------------------------------------------------------------------------------------------
00294 
00295 class DObjConstIterator
00296 {
00297 public:
00298      
00300     DObjConstIterator();
00302     DObjConstIterator(const DataObject* _dObj, int pos = 0);
00304     DObjConstIterator(const DObjConstIterator& it);
00305     
00307     DObjConstIterator& operator = (const DObjConstIterator& it);
00309     uchar* operator *() const;
00311     uchar* operator [](int i) const;
00312     
00314     DObjConstIterator& operator += (int ofs);
00316     DObjConstIterator& operator -= (int ofs);
00318     DObjConstIterator& operator --();
00320     DObjConstIterator operator --(int);
00322     DObjConstIterator& operator ++();
00324     DObjConstIterator operator ++(int);
00325 
00326     bool operator == (const DObjConstIterator& dObjIt);
00327     bool operator != (const DObjConstIterator& dObjIt);
00328     bool operator < (const DObjConstIterator& dObjIt);
00329     bool operator > (const DObjConstIterator& dObjIt);
00330     bool operator <= (const DObjConstIterator& dObjIt);
00331     bool operator >= (const DObjConstIterator& dObjIt);
00332 
00333 protected:
00334     void seekAbs(int ofs);
00335     void seekRel(int ofs);
00336     
00337     const DataObject* dObj;
00338     bool   planeContinuous;
00339     size_t elemSize;
00340     uchar* ptr;
00341     uchar* sliceStart;
00342     uchar* sliceEnd;
00343     int plane;
00344 };
00345 
00346 //----------------------------------------------------------------------------------------------------------------------------------
00347 class DObjIterator : public DObjConstIterator
00348 {
00349 public:
00350      
00352     DObjIterator();
00354     DObjIterator(DataObject* _dObj, int pos = 0);
00356     DObjIterator(const DObjIterator& it);
00357     
00359     DObjIterator& operator = (const DObjIterator& it);
00361     uchar* operator *();
00363     uchar* operator [](int i);
00364     
00366     DObjIterator& operator += (int ofs);
00368     DObjIterator& operator -= (int ofs);
00370     DObjIterator& operator --();
00372     DObjIterator operator --(int);
00374     DObjIterator& operator ++();
00376     DObjIterator operator ++(int);
00377 };
00378 
00379 //----------------------------------------------------------------------------------------------------------------------------------
00380 class DataObject
00381 {
00382     private:
00383 
00385 
00399         //length(sizes) == length(steps)
00400         void createHeader(const unsigned char dimensions, const size_t *sizes, const size_t *steps, const size_t elemSize)
00401         {
00402             if(dimensions == 1)
00403             {
00404                 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__));
00405             }
00406 
00407             m_dims = dimensions;
00408 
00409             if(dimensions > 0)
00410             {
00411 
00412                 if (m_roi.m_p)
00413                 {
00414                     if (*(m_roi.m_p-1) != dimensions)
00415                     {
00416                         delete[] (m_roi.m_p - 1);
00417 
00418                         m_roi.m_p = new size_t [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00419                         m_osize.m_p = static_cast<size_t *>(m_roi.m_p + dimensions) + 1;
00420                         m_osize.m_p[-1] = dimensions;
00421                         m_size.m_p = static_cast<size_t *>(m_osize.m_p + dimensions) + 1;
00422                         m_size.m_p[-1] = dimensions;
00423                         m_roi.m_p = m_roi.m_p + 1;
00424                         m_roi.m_p[-1] = dimensions;
00425                     }
00426                 }
00427                 else
00428                 {
00429                     m_roi.m_p = new size_t [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00430                     m_osize.m_p = static_cast<size_t *>(m_roi.m_p + dimensions) + 1;
00431                     m_osize.m_p[-1] = dimensions;
00432                     m_size.m_p = static_cast<size_t *>(m_osize.m_p + dimensions) + 1;
00433                     m_size.m_p[-1] = dimensions;
00434                     m_roi.m_p = m_roi.m_p + 1;
00435                     m_roi.m_p[-1] = dimensions;
00436                 }
00437 
00438                 for (uchar n = 0 ; n < dimensions ; n++)
00439                 {
00440                     m_size.m_p[n] = sizes[n];
00441                     m_roi.m_p[n] = 0;
00442 
00443                     if(steps == NULL || n == 0)
00444                     {
00445                         m_osize.m_p[n] = sizes[n];
00446                     }
00447                     else if(n == dimensions - 1) //last element
00448                     {
00449                         m_osize.m_p[n] = steps[n-1] / elemSize;
00450                     }
00451                     else /*if(n < dimensions -1)*/
00452                     {
00453                         m_osize.m_p[n] = steps[n-1] / steps[n];
00454                     }
00455                 }
00456             }
00457         }
00458 
00460 
00473         void createHeaderWithROI(const unsigned char dimensions, const size_t *sizes, const size_t *osizes = NULL, const size_t *roi = NULL)
00474         {
00475             if(dimensions == 1)
00476             {
00477                 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__));
00478             }
00479 
00480             m_dims = dimensions;
00481 
00482             if(dimensions > 0)
00483             {
00484 
00485                 if (m_roi.m_p)
00486                 {
00487                     if (*(m_roi.m_p-1) != dimensions)
00488                     {
00489                         delete[] (m_roi.m_p-1);
00490 
00491                         m_roi.m_p = new size_t [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00492                         m_osize.m_p = static_cast<size_t *>(m_roi.m_p + dimensions) + 1;
00493                         m_osize.m_p[-1] = dimensions;
00494                         m_size.m_p = static_cast<size_t *>(m_osize.m_p + dimensions) + 1;
00495                         m_size.m_p[-1] = dimensions;
00496                         m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one
00497                         m_roi.m_p[-1] = dimensions;
00498                     }
00499                 }
00500                 else
00501                 {
00502                     m_roi.m_p = new size_t [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00503                     m_osize.m_p = static_cast<size_t *>(m_roi.m_p + dimensions) + 1;
00504                     m_osize.m_p[-1] = dimensions;
00505                     m_size.m_p = static_cast<size_t *>(m_osize.m_p + dimensions) + 1;
00506                     m_size.m_p[-1] = dimensions;
00507                     m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one
00508                     m_roi.m_p[-1] = dimensions;
00509                 }
00510 
00511                 for (uchar n = 0; n < dimensions; n++)
00512                 {
00513                     m_size.m_p[n] = sizes[n];
00514 
00515                     if (osizes)
00516                     {
00517                         m_osize.m_p[n] = osizes[n];
00518                     }
00519                     else
00520                     {
00521                         m_osize.m_p[n] = sizes[n];
00522                     }
00523 
00524                     if (roi)
00525                     {
00526                         m_roi.m_p[n] = roi[n];
00527                     }
00528                     else
00529                     {
00530                         m_roi.m_p[n] = 0;
00531                     }
00532                 }
00533             }
00534         }
00535 
00536         void create(const unsigned char dimensions, const size_t *sizes, const int type, const unsigned char continuous, const uchar* continuousDataPtr = NULL, const size_t* steps = NULL);  
00538         void create(const unsigned char dimensions, const size_t *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes);
00539 
00540         void freeData(void);     
00542         void secureFreeData(void); 
00546         //----------------------------------------------------------------------------------------------------------------------------------
00547         ito::RetVal matNumToIdx(const size_t matNum, size_t *matIdx) const;
00548 
00550 
00558         inline ito::RetVal matIdxToNum(const unsigned int *matIdx, size_t *matNum) const
00559         {
00560            *matNum = 0;
00561            if (m_dims <= 2)
00562            {
00563                  return 0;
00564            }
00565 
00566            size_t planeSize = 1;
00567 
00568            for (int n = m_dims - 3; n >= 0; n--)
00569            {
00570         #if __ITODEBUG
00571                  if (((size_t)matIdx[n] + m_roi[n]) >= m_osize[n])
00572                  {
00573                     cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
00574                  }
00575         #endif
00576                  (*matNum) += ((size_t)matIdx[n] + m_roi[n]) * planeSize; //CAST_TODO
00577                  planeSize *= m_osize[n];
00578            }
00579 
00580            return 0;
00581         }
00582 
00583         struct MSize
00584         {
00585             inline MSize() : m_p(NULL) {}
00586             //inline MSize(size_t *_p, char *_transp) : m_p(_p) {}
00587 //            Size operator()() const;
00588             inline size_t operator [] (const int dim) const
00589             {
00590                 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory
00591             };
00592 //            inline unsigned int& operator [](const int i) { return m_p[i]; };
00593             inline operator const size_t * () const { return m_p; }
00594             bool operator == (const MSize& sz) const
00595             {
00596                 if(m_p == NULL || sz.m_p == NULL)
00597                 {
00598                     return sz.m_p == m_p;
00599                 }
00600 
00601                 size_t d = m_p[-1], dsz = sz.m_p[-1];
00602                 if( d != dsz )
00603                     return false;
00604                 if( d == 2 )
00605                 {                    
00606                     return m_p[0] == sz.m_p[0] && m_p[1] == sz.m_p[1];            
00607                 }
00608 
00609                 for( size_t i = 0; i < d - 2; i++ )
00610                 {
00611                     if( m_p[i] != sz.m_p[i] )
00612                     {
00613                         return false;
00614                     }
00615                 }                
00616                 return (m_p[d - 2] == sz.m_p[d - 2]) && (m_p[d - 1] == sz.m_p[d - 1]);               
00617             }
00618 
00619             inline bool operator != (const MSize& sz) const { return !(*this == sz); }
00620 
00621             size_t *m_p;
00622         };
00623 
00624         struct MROI
00625         {
00626             inline MROI() : m_p(NULL) {};
00627             //inline MROI(size_t *_p, char *_transp) : m_p(_p), m_pTransp(_transp) {}
00628             inline size_t operator [] (const int dim) const
00629             {
00630                 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory
00631             }
00632 
00633 //            inline unsigned int operator () (unsigned char dim, unsigned char beginEnd) const { beginEnd > 0 ? beginEnd = 1 : beginEnd = 0; return m_p[dim + beginEnd]; };
00634 //            inline unsigned int & operator () (unsigned char dim, unsigned char beginEnd) { return m_p[dim + beginEnd]; };
00635             bool operator == (const MROI & rroi) const
00636             {
00637                 if(m_p == NULL || rroi.m_p == NULL)
00638                 {
00639                     return rroi.m_p == m_p;
00640                 }
00641 
00642                 if (m_p[-1] != rroi.m_p[-1])
00643                 {
00644                     return false;
00645                 }
00646 
00647                 size_t d = m_p[-1];
00648                 for (size_t n = 0; n < d - 2; n++)
00649                 {
00650                     if (m_p[n] != rroi.m_p[n])
00651                     {
00652                         return false;
00653                     }
00654                 }
00655 
00656                 return m_p[d - 2] == rroi.m_p[d - 2] && m_p[d - 1] == rroi.m_p[d - 1];
00657                 
00658             }
00659 
00660             size_t *m_p;
00661         };
00662 
00663                 DataObject(const DataObject& dObj, bool transposed);    
00666         char    m_continuous;                        
00667         char    m_owndata;                           
00668         int     m_type;                              
00669         int     *m_pRefCount;                        
00670         int     m_dims;                              
00671         MSize   m_osize;                             
00672         MROI    m_roi;                               
00673         MSize   m_size;                              
00674 //        std::vector<int *>  m_data;                  /*!< vector with references to each matrix-plane. Must be cast to cv::Mat_<"m_type"> */
00675         int     **m_data;
00676         ReadWriteLock      *m_objSharedDataLock;     
00677         DataObjectTags     *m_pDataObjectTags;        
00678         ReadWriteLock       m_objHeaderLock;         
00680         inline int mdata_realloc(const size_t size)
00681         {
00682             static size_t sizeofs = sizeof(size_t) / sizeof(int *);
00683 
00684             if (m_data)
00685             {
00686                 m_data = static_cast<int **>(realloc(m_data - sizeofs, size * sizeof(int *) + sizeof(size_t)));
00687             }
00688             else
00689             {
00690                 size_t numBytes = size * sizeof(int *) + sizeof(size_t);
00691                 m_data = static_cast<int **>(calloc(numBytes, 1));
00692                 memset( m_data, 0, numBytes );
00693             }
00694             (*reinterpret_cast<size_t*>(m_data)) = size;
00695             m_data += sizeofs;
00696             return 0;
00697         }
00698         inline size_t mdata_size(void) const
00699         {
00700             static size_t sizeofs = sizeof(size_t) / sizeof(int *);
00701             if (!m_data)
00702                 return 0;
00703             else
00704                 return (*reinterpret_cast<size_t *>(m_data - sizeofs));
00705         }
00706         inline int mdata_free()
00707         {
00708             static size_t sizeofs = sizeof(size_t) / sizeof(int *);
00709             if (m_data)
00710             {
00711                 int **ptr = m_data - sizeofs;
00712                 free(ptr);
00713             }
00714             m_data = NULL;
00715             return 0;
00716         }
00717 
00718         //low-level, templated methods
00719         //most low-level methods are marked "friend" such that they can access private members of their data object parameters
00720         template<typename _Tp> friend RetVal CreateFunc(DataObject *dObj, const unsigned char dimensions, const size_t *sizes, const unsigned char continuous, const uchar* continuousDataPtr, const size_t* steps);
00721         template<typename _Tp> friend RetVal CreateFuncWithCVPlanes(DataObject *dObj, const unsigned char dimensions, const size_t *sizes, const cv::Mat* planes, const unsigned int nrOfPlanes);
00722         template<typename _Tp> friend RetVal FreeFunc(DataObject *dObj);
00723         template<typename _Tp> friend RetVal SecureFreeFunc(DataObject *dObj);
00724         template<typename _Tp> friend RetVal CopyToFunc(const DataObject &lhs, DataObject &rhs, unsigned char regionOnly);
00725         template<typename _Tp> friend RetVal ConvertToFunc(const DataObject &lhs, DataObject &rhs, const int type, const double alpha, const double beta);
00726         template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, const int *lims);
00727         template<typename _Tp> friend RetVal MinMaxLocFunc(const DataObject &dObj, double *minVal, double *maxVal, size_t *minPos, size_t *maxPos);
00728         template<typename _Tp> friend RetVal AssignScalarFunc(const DataObject *src, const ito::tDataType type, const void *scalar);
00729         template<typename _Tp> friend RetVal MakeContinuousFunc(const DataObject &dObj, DataObject &resDObj);
00730         template<typename _Tp> friend RetVal EvaluateTransposeFlagFunc(DataObject *dObj);
00731         template<typename _Tp> friend RetVal CalcMinMaxValues(DataObject *lhs, double &result_min, double &result_max, const int cmplxSel = 0);
00732 
00733         // more friends due to change of std::vector to int ** for m_data ...
00734         template<typename _Tp> friend RetVal GetRangeFunc(DataObject *dObj, const int dtop, const int dbottom, const int dleft, const int dright);
00735         template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, int dtop, int dbottom, int dleft, int dright);
00736 
00737     public:
00738         size_t seekMat(const size_t matNum, const size_t numMats) const;
00739         size_t seekMat(const size_t matNum) const;
00740         size_t calcNumMats(void) const;
00741 
00742         // TAGSPACEFUNCTIONS
00743 
00745         inline double getValueOffset() const
00746         {
00747             if(!m_pDataObjectTags) return 0.0; // default
00748             return m_pDataObjectTags->m_valueOffset;
00749         }
00750 
00752         inline double getValueScale() const
00753         {
00754             if(!m_pDataObjectTags) return 1.0; // default
00755             return m_pDataObjectTags->m_valueScale;
00756         }
00757 
00759         inline const std::string getValueUnit() const
00760         {
00761             if(!m_pDataObjectTags) return std::string(); //default
00762             return m_pDataObjectTags->m_valueUnit;
00763         }
00764 
00766         inline std::string getValueDescription() const
00767         {
00768             if(!m_pDataObjectTags) return std::string(); //default
00769             return m_pDataObjectTags->m_valueDescription;
00770         }
00771 
00773         inline double getAxisOffset(const int axisNum) const
00774         {
00775             if(axisNum < 0 || axisNum >= m_dims)
00776             {
00777                 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__));
00778             }
00779             if(!m_pDataObjectTags) return 0.0; // default
00780            
00781             return m_pDataObjectTags->m_axisOffsets[axisNum] - m_roi[axisNum];
00782         }
00783 
00785         inline double getAxisScale(const int axisNum) const
00786         {
00787             if(axisNum < 0 || axisNum >= m_dims)
00788             {
00789                 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__));
00790             }
00791             if(!m_pDataObjectTags) return 1.0; // default
00792 
00793             return m_pDataObjectTags->m_axisScales[axisNum];
00794         }
00795 
00797         inline const std::string getAxisUnit(const int axisNum, bool &validOperation) const
00798         {
00799             if(axisNum < 0 || axisNum >= m_dims)
00800             {
00801                                 validOperation = false;
00802                 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__));
00803             }
00804             if(!m_pDataObjectTags)
00805             {
00806                 validOperation = false;
00807                 return std::string(); //error
00808             }
00809             validOperation = true;            
00810             return m_pDataObjectTags->m_axisUnit[axisNum];
00811         }
00812 
00814         const inline std::string getAxisDescription(const int axisNum, bool &validOperation) const
00815         {
00816             if(axisNum < 0 || axisNum >= m_dims)
00817             {
00818                                 validOperation = false;
00819                 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__));
00820             }
00821             if(!m_pDataObjectTags)
00822             {
00823                 validOperation = false;
00824                 return std::string(); //error
00825             }
00826 
00827             validOperation = true;          
00828             return m_pDataObjectTags->m_axisDescription[axisNum];
00829         }
00830 
00831         inline DataObjectTagType getTag(const std::string key, bool &validOperation) const
00832         {
00833             validOperation = false;
00834             if(!m_pDataObjectTags)
00835             {
00836                 return DataObjectTagType(); //error
00837             }
00838             //std::map<std::string, std::string>::iterator it = m_pDataObjectTags->m_tags.find(key);
00839             std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.find(key);
00840             if(it != m_pDataObjectTags->m_tags.end())
00841             {
00842                 validOperation = true;
00843                 return it->second;
00844             }
00845             return DataObjectTagType();
00846         }
00847 
00849         //inline bool getTagByIndex(const int tagNumber, std::string &key, std::string &value) const
00850         inline bool getTagByIndex(const int tagNumber, std::string &key, DataObjectTagType &value) const
00851         {
00852             if(!m_pDataObjectTags)
00853             {
00854                 key = std::string();
00855                 value = std::string();
00856                 return false;
00857             }
00858 
00859             if((tagNumber < 0) || ((size_t)(tagNumber + 1) > m_pDataObjectTags->m_tags.size()))
00860             {
00861                 key = std::string();
00862                 value = std::string();
00863                 return false;
00864             }
00865             //std::map<std::string,std::string>::iterator it = m_pDataObjectTags->m_tags.begin();
00866             std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.begin();
00867             for(int i = 0; i < tagNumber; i++)
00868             {
00869                 it++;
00870             }
00871 
00872             key = (*it).first;
00873             value = (*it).second;
00874             return true;
00875         }
00876 
00878         inline std::string getTagKey(const int tagNumber, bool &validOperation) const
00879         {
00880             if(!m_pDataObjectTags)
00881             {
00882                 validOperation = false;
00883                 return std::string(""); //error
00884             }
00885             if((tagNumber < 0) || ((size_t)(tagNumber + 1) > m_pDataObjectTags->m_tags.size()))
00886             {
00887                 validOperation = false;
00888                 return std::string(""); //does not exist
00889             }
00890             //std::map<std::string,std::string>::iterator it = m_pDataObjectTags->m_tags.begin();
00891             std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.begin();
00892             validOperation = true;
00893             for(int i = 0; i < tagNumber; i++)
00894             {
00895                 it++;
00896             }
00897             return (*it).first;
00898         }
00899 
00901         inline int getTagListSize() const
00902         {
00903             if(!m_pDataObjectTags) return 0; //error
00904             return static_cast<int>(m_pDataObjectTags->m_tags.size());
00905         }
00906 
00907      //   inline void setValueOffset(double offset) { m_valueOffset =offset; }
00908      //   inline void setValueScale(double scale) { m_valueScale =scale; }
00909 
00911         inline int setValueUnit(const std::string &unit)
00912         {
00913             if(!m_pDataObjectTags) return 1;    //error
00914             m_pDataObjectTags->m_valueUnit = unit;
00915             return 0;
00916         }
00917 
00919         inline int setValueDescription(const std::string &description)
00920         {
00921             if(!m_pDataObjectTags) return 1;    //error
00922             m_pDataObjectTags->m_valueDescription = description;
00923             return 0;
00924         }
00925 
00926         //inline lead to a linker error on MSVC when calling from several methods
00927         int setAxisOffset(const unsigned int axisNum, const double offset);
00928         int setAxisScale(const unsigned int axisNum, const double scale);
00929         int setAxisUnit(const unsigned int axisNum, const std::string &unit);
00930         int setAxisDescription(const unsigned int axisNum, const std::string &description);
00931         int setTag(const std::string &key, const DataObjectTagType &value);
00932         bool existTag(const std::string &key) const;
00933         bool deleteTag(const std::string &key);
00934         bool deleteAllTags();
00935         int addToProtocol(const std::string &value);
00936 
00937 
00948         inline double getPhysToPix(const unsigned int dim, const double phys, bool &isInsideImage) const
00949         {
00950             double tPx = 0.0;
00951             if(static_cast<int>(dim) >= m_dims)
00952             {
00953                 if(phys == 0.0)
00954                 {
00955                     isInsideImage = true;
00956                 }
00957                 else
00958                 {
00959                     isInsideImage = false;
00960                 }
00961                 return 0.0;
00962             }
00963 
00964             if(m_pDataObjectTags)
00965             {
00966                 tPx = (phys / getAxisScale(dim) + getAxisOffset(dim));
00967             }
00968             else
00969             {
00970                 tPx = phys;
00971             }
00972 
00973             if(tPx > getSize(dim) - 1)
00974             {
00975                 isInsideImage = false;
00976                 tPx = static_cast<double>(getSize(dim)- 1);
00977             }
00978             else if( tPx < 0)
00979             {
00980                 isInsideImage = false;
00981                 tPx = 0;
00982             }
00983             else
00984             {
00985                 isInsideImage = true;
00986             }
00987 
00988             return tPx;
00989         }
00990 
00994         inline int getPhysToPix2D(const double physY, double &tPxY, bool &isInsideImageY, const double physX, double &tPxX, bool &isInsideImageX) const
00995         {
00996             if(m_dims < 2)
00997             {           
00998                     tPxY = physY;
00999                     if(physY != 0.0)
01000                     {
01001                         isInsideImageY = false;
01002                     }
01003 
01004                     if(m_pDataObjectTags)
01005                     {
01006                         tPxX = physX / m_pDataObjectTags->m_axisScales[0] + m_pDataObjectTags->m_axisOffsets[0];
01007                     }
01008                     else
01009                     {
01010                         tPxX = physX;
01011                     }
01012 
01013                     if(tPxX > m_size[0] - 1)
01014                     {
01015                         isInsideImageX = false;
01016                         tPxX = static_cast<double>(m_size[0] - 1);
01017                     }                
01018             }
01019             else
01020             {             
01021                     if(m_pDataObjectTags)
01022                     {
01023                         tPxX = physX / m_pDataObjectTags->m_axisScales[m_dims - 1] + m_pDataObjectTags->m_axisOffsets[m_dims - 1];
01024                         tPxY = physY / m_pDataObjectTags->m_axisScales[m_dims - 2] + m_pDataObjectTags->m_axisOffsets[m_dims - 2];
01025                     }
01026                     else
01027                     {
01028                         tPxX = physX;
01029                         tPxY = physY;
01030                     }
01031 
01032                     if(tPxY > m_size[m_dims - 2] - 1)
01033                     {
01034                         isInsideImageY = false;
01035                         tPxY = static_cast<double>(m_size[m_dims - 2] - 1);
01036                     }
01037                     if(tPxX > m_size[m_dims - 1] - 1)
01038                     {
01039                         isInsideImageX = false;
01040                         tPxY = static_cast<double>(m_size[m_dims - 1] - 1);
01041                     }                
01042             }
01043 
01044             if(tPxX < 0)
01045             {
01046                 tPxX = 0;
01047                 isInsideImageX = false;
01048             }
01049             if(tPxY < 0)
01050             {
01051                 tPxY = 0;
01052                 isInsideImageY = false;
01053             }
01054             return 0;
01055         }
01056 
01066         inline double getPixToPhys(const unsigned int dim, const double pix, bool &isInsideImage) const
01067         {
01068             double tPhys = 0.0;
01069             if(static_cast<int>(dim) >= m_dims)
01070             {
01071                 if(pix == 0)
01072                 {
01073                     isInsideImage = true;
01074                 }
01075                 else
01076                 {
01077                     isInsideImage = false;
01078                 }
01079                 return 0.0;
01080             }
01081             if(m_pDataObjectTags)
01082             {
01083                 tPhys = (pix - getAxisOffset(dim)) * getAxisScale(dim);
01084             }
01085             else
01086             {
01087                 tPhys = pix;
01088             }
01089 
01090             if((pix > getSize(dim) - 1) || (pix < 0))
01091             {
01092                 isInsideImage = false;
01093             }
01094             else
01095             {
01096                 isInsideImage = true;
01097             }
01098 
01099             return tPhys;
01100         }
01101 
01116         inline RetVal setXYRotationalMatrix(double r11, double r12, double r13, double r21, double r22, double r23, double r31, double r32, double r33)
01117         {
01118             if(!m_pDataObjectTags) return RetVal(retError, 0, "Tagspace not initialized"); // error
01119             m_pDataObjectTags->m_rotMatrix[0] = r11;
01120             m_pDataObjectTags->m_rotMatrix[1] = r12;
01121             m_pDataObjectTags->m_rotMatrix[2] = r13;
01122             m_pDataObjectTags->m_rotMatrix[3] = r21;
01123             m_pDataObjectTags->m_rotMatrix[4] = r22;
01124             m_pDataObjectTags->m_rotMatrix[5] = r23;
01125             m_pDataObjectTags->m_rotMatrix[6] = r31;
01126             m_pDataObjectTags->m_rotMatrix[7] = r32;
01127             m_pDataObjectTags->m_rotMatrix[8] = r33;
01128             return retOk;
01129         }
01130 
01145         inline RetVal getXYRotationalMatrix(double &r11, double &r12, double &r13, double &r21, double &r22, double &r23, double &r31, double &r32, double &r33) const
01146         {
01147             if(!m_pDataObjectTags) return RetVal(retError, 0, "Tagspace not initialized"); // error
01148             r11 = m_pDataObjectTags->m_rotMatrix[0];
01149             r12 = m_pDataObjectTags->m_rotMatrix[1];
01150             r13 = m_pDataObjectTags->m_rotMatrix[2];
01151             r21 = m_pDataObjectTags->m_rotMatrix[3];
01152             r22 = m_pDataObjectTags->m_rotMatrix[4];
01153             r23 = m_pDataObjectTags->m_rotMatrix[5];
01154             r31 = m_pDataObjectTags->m_rotMatrix[6];
01155             r32 = m_pDataObjectTags->m_rotMatrix[7];
01156             r33 = m_pDataObjectTags->m_rotMatrix[8];
01157             return retOk;
01158         }
01159 
01160         RetVal copyTagMapTo(DataObject &rhs) const;  
01161         RetVal copyAxisTagsTo(DataObject &rhs) const;  
01163         // END TAGSPACE
01164 
01166         inline int getDims(void) const { return m_dims; }
01167 
01169         inline int getType(void) const { return m_type; }
01170 
01172         inline char getContinuous(void) const { return m_continuous; }
01173 
01175         inline char getOwnData(void) const { return m_owndata; }
01176         
01178 
01182         inline size_t getTotal() const
01183         {
01184             int dims = getDims();
01185             size_t total = dims > 0 ? 1 : 0;
01186             for(int i = 0 ; i<dims ; i++)
01187             {
01188                 total *= getSize(i);
01189             }
01190             return total;
01191 
01192         }
01193 
01195 
01199         inline size_t getOriginalTotal() const
01200         {
01201             int dims = getDims();
01202             size_t total = dims > 0 ? 1 : 0;
01203             for(int i = 0 ; i<dims ; i++)
01204             {
01205                 total *= m_osize[i];
01206             }
01207             return total;
01208 
01209         }
01210 
01212 
01220         inline void lockRead()
01221         {
01222             m_objHeaderLock.lockRead();
01223             if(m_objSharedDataLock) m_objSharedDataLock->lockRead();
01224         }
01225 
01227 
01230         inline void lockWrite()
01231         {
01232             m_objHeaderLock.lockWrite();
01233             if(m_objSharedDataLock) m_objSharedDataLock->lockWrite();
01234         }
01235 
01237 
01240         inline void unlock()
01241         {
01242             if(m_objSharedDataLock) m_objSharedDataLock->unlock();
01243             m_objHeaderLock.unlock();
01244         }
01245         
01246         RetVal copyTo(DataObject &rhs, unsigned char regionOnly = 0);   
01247         RetVal convertTo(DataObject &rhs, const int type, const double alpha=1, const double beta=0 ) const;
01248         RetVal deepCopyPartial(DataObject &rhs);                         
01252 //        std::vector<int *> get_mdata(void);
01253         int ** get_mdata(void);
01254 //        std::vector<int *> get_mdata(void) const;
01255         int ** get_mdata(void) const;
01256 
01258 
01261         inline MSize getSize(void) { return m_size; }
01262 
01264 
01267         inline const MSize getSize(void) const { return m_size; }
01268 
01270 
01274         size_t getSize(int index) const
01275         {
01276             if(index < 0 || index >= m_dims) return -1;            
01277             else
01278             {
01279 
01280                 return m_size[index];
01281             }
01282         }
01283 
01285 
01289         size_t getOriginalSize(int index) const
01290         {
01291             if(index < 0 || index >= m_dims) return -1;           
01292             else
01293             {
01294 
01295                 return m_osize[index];
01296             }
01297         }
01298 
01300         DObjIterator begin();
01302         DObjIterator end();
01303 
01304         DObjConstIterator constBegin() const;
01305         DObjConstIterator constEnd() const;
01306 
01307         
01308 
01309 
01311 
01314         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) {}
01315 
01317 
01325         DataObject(const size_t 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)
01326         {
01327             size_t sizes[2] = {1, size};
01328             this->create(2, sizes, type, 1);
01329             //DataObject(1, size, type);
01330         }
01331 
01333 
01341         DataObject(const size_t sizeY, const size_t 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)
01342         {
01343             size_t sizes[2] = {sizeY, sizeX};
01344             this->create(2, sizes, type, 1);
01345         }
01346 
01348 
01358         DataObject(const size_t sizeZ, const size_t sizeY, const size_t 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)
01359         {
01360              size_t sizes[3] = {sizeZ, sizeY, sizeX};
01361 
01362             this->create(3, sizes, type, m_continuous);
01363         }
01364 
01366 
01380         DataObject(const size_t sizeZ, const size_t sizeY, const size_t sizeX, const int type, const uchar* continuousDataPtr,  const size_t* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0)
01381         {
01382             size_t sizes[3] = {sizeZ, sizeY, sizeX};
01383 
01384             this->create(3, sizes, type, m_continuous, continuousDataPtr, steps);
01385         }
01386 
01388 
01397         DataObject(const unsigned char dimensions, const size_t *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)
01398         {
01399             this->create(dimensions, sizes, type, m_continuous);
01400         }
01401 
01403 
01416         DataObject(const unsigned char dimensions, const size_t *sizes, const int type, const uchar* continuousDataPtr, const size_t* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0)
01417         {
01418             this->create(dimensions, sizes, type, m_continuous, continuousDataPtr, steps);
01419         }
01420 
01421         DataObject(const unsigned char dimensions, const size_t *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)
01422         {
01423             this->create(dimensions, sizes, type, planes, nrOfPlanes);
01424         }
01425 
01426         DataObject(const DataObject& copyConstr);    
01428 
01429 
01435         ~DataObject(void)
01436         {
01437             freeData();
01438         }
01439 
01441         DataObject & operator = (const cv::Mat &rhs);
01442         DataObject & operator = (const DataObject &rhs);
01443         DataObject & operator = (const int8 value);          
01444         DataObject & operator = (const uint8 value);         
01445         DataObject & operator = (const int16 value);         
01446         DataObject & operator = (const uint16 value);        
01447         DataObject & operator = (const int32 value);         
01448         DataObject & operator = (const uint32 value);        
01449         DataObject & operator = (const float32 value);       
01450         DataObject & operator = (const float64 value);       
01451         DataObject & operator = (const complex64 value);     
01452         DataObject & operator = (const complex128 value);    
01455         DataObject & operator += (const DataObject &rhs);
01456         DataObject & operator += (const float64 value);
01457 
01458         DataObject operator + (const DataObject &rhs);
01459         DataObject operator + (const float64 value);
01460 
01461         DataObject & operator -= (const DataObject &rhs);
01462         DataObject & operator -= (const float64 value);
01463 
01464         DataObject operator - (const DataObject &rhs);
01465         DataObject operator - (const float64 value);
01466 
01467         DataObject & operator *= (const DataObject &rhs);
01468         DataObject & operator *= (const float64 factor);
01469 
01470         DataObject operator * (const DataObject &rhs);
01471         DataObject operator * (const float64 factor);
01472 
01473         // Comparison Operators
01474         DataObject operator < (DataObject &rhs);
01475         DataObject operator > (DataObject &rhs);
01476         DataObject operator <= (DataObject &rhs);
01477         DataObject operator >= (DataObject &rhs);
01478         DataObject operator == (DataObject &rhs);
01479         DataObject operator != (DataObject &rhs);
01480 
01481 
01482         // bitshift operators
01483         DataObject operator << (const unsigned int shiftbit);
01484         DataObject & operator <<= (const unsigned int shiftbit);
01485         DataObject operator >> (const unsigned int shiftbit);
01486         DataObject & operator >>= (const unsigned int shiftbit);
01487 
01488         // bitwise operators
01489         DataObject operator & (const DataObject & rhs);
01490         DataObject & operator &= (const DataObject & rhs);
01491         DataObject operator | (const DataObject & rhs);
01492         DataObject & operator |= (const DataObject & rhs);
01493         DataObject operator ^ (const DataObject & rhs);
01494         DataObject & operator ^= (const DataObject & rhs);
01495 
01496         // allocates matrix with zero values
01497         RetVal zeros(const int type);
01498         RetVal zeros(const size_t size, const int type);
01499         RetVal zeros(const size_t sizeY, const size_t sizeX, const int type);
01500         RetVal zeros(const size_t sizeZ, const size_t sizeY, const size_t sizeX, const int type, const unsigned char continuous = 0);
01501         RetVal zeros(const unsigned char dimensions, const size_t *sizes, const int type, const unsigned char continuous = 0);
01502 
01503         // allocates matrix with all values set to one
01504         RetVal ones(const int type);
01505         RetVal ones(const size_t size, const int type);
01506         RetVal ones(const size_t sizeY, const size_t sizeX, const int type);
01507         RetVal ones(const size_t sizeZ, const size_t sizeY, const size_t sizeX, const int type, const unsigned char continuous = 0);
01508         RetVal ones(const unsigned char dimensions, const size_t *sizes, const int type, const unsigned char continuous = 0);
01509 
01510         // allocates matrix with uniform distributed noise
01511         RetVal rand(const int type, const bool randMode = false);
01512         RetVal rand(const size_t size, const int type, const bool randMode = false);
01513         RetVal rand(const size_t sizeY, const size_t sizeX, const int type, const bool randMode = false);
01514         RetVal rand(const size_t sizeZ, const size_t sizeY, const size_t sizeX, const int type, const bool randMode, const unsigned char continuous = 0);
01515         RetVal rand(const unsigned char dimensions, const size_t *sizes, const int type, const bool randMode, const unsigned char continuous = 0);
01516 
01517         // allocates matrix with eye-matrix representation
01518         RetVal eye(const int type);
01519         RetVal eye(const size_t size, const int type);
01520 
01521         RetVal conj();
01522         DataObject adj() const;
01523         DataObject trans() const;
01524 
01525         //RetVal makeContinuous(void);
01526 
01527         DataObject mul(const DataObject &mat2, const double scale = 1.0);
01528         DataObject div(const DataObject &mat2, const double scale = 1.0);
01529 
01530         DataObject squeeze() const;
01531 
01532         size_t elemSize() const;
01533 
01534 /*
01535         // Adressing operators ()
01536         // You should NOT use DataObject::operator here! Otherwise the MsVc compiler will hate you  - at least today: 30.03.2011
01537         template<typename _Tp> _Tp& operator () (const unsigned int x) const;
01538         template<typename _Tp> _Tp& operator () (const unsigned int x);
01539         template<typename _Tp> _Tp& operator () (const unsigned int y, const unsigned int x) const;
01540         template<typename _Tp> _Tp& operator () (const unsigned int y, const unsigned int x);
01541         template<typename _Tp> _Tp& operator () (const unsigned int z, const unsigned int y, const unsigned int x) const;
01542         template<typename _Tp> _Tp& operator () (const unsigned int z, const unsigned int y, const unsigned int x);
01543         template<typename _Tp> _Tp& operator () (const unsigned int *idx) const;
01544         template<typename _Tp> _Tp& operator () (const unsigned int *idx);
01545         DataObject operator () (const ito::Range rowRange, const ito::Range colRange);
01546         DataObject operator () (ito::Range *ranges);
01547 
01548 */
01549         // Adressing functions
01550 
01552 
01556         template<typename _Tp> _Tp& at(const int x) const
01557         {
01558          #if __ITODEBUG
01559             if ((m_dims != 1) && !((m_dims == 2) && ((m_size[0] == 1) || (m_size[1] == 1))))
01560             {
01561                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01562             }
01563          #endif
01564             if (m_dims == 1)
01565             {
01566          #if __ITODEBUG
01567                if ((size_t)x >= m_size[0])
01568                {
01569                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01570                }
01571          #endif
01572                return (*(cv::Mat_<_Tp> *)(m_data[0]))(0, x);
01573             }
01574             else if (m_size[0] == 1)
01575             {
01576          #if __ITODEBUG
01577                if ((size_t)x >= m_size[1])
01578                {
01579                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01580                }
01581          #endif
01582                return (*(cv::Mat_<_Tp> *)(m_data[0]))(0, x);
01583             }
01584             else
01585             {
01586          #if __ITODEBUG
01587                if ((size_t)x >= m_size[0])
01588                {
01589                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01590                }
01591          #endif
01592                return (*(cv::Mat_<_Tp> *)(m_data[0]))(x, 0);
01593             }
01594         }
01595 
01597 
01601         template<typename _Tp> _Tp& at(const int x)
01602         {
01603          #if __ITODEBUG
01604             if ((m_dims != 1) && !((m_dims == 2) && ((m_size[0] == 1) || (m_size[1] == 1))))
01605             {
01606                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01607             }
01608          #endif
01609             if (m_dims == 1)
01610             {
01611          #if __ITODEBUG
01612                if ((size_t)x >= m_size[0])
01613                {
01614                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01615                }
01616          #endif
01617                return (*(cv::Mat_<_Tp> *)(m_data[0]))(0, x);
01618             }
01619             else if (m_size[0] == 1)
01620             {
01621          #if __ITODEBUG
01622                if ((size_t)x >= m_size[1])
01623                {
01624                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01625                }
01626          #endif
01627                return (*(cv::Mat_<_Tp> *)(m_data[0]))(0, x);
01628             }
01629             else
01630             {
01631          #if __ITODEBUG
01632                if ((size_t)x >= m_size[0])
01633                {
01634                   cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
01635                }
01636          #endif
01637                return (*(cv::Mat_<_Tp> *)(m_data[0]))(x, 0);
01638             }
01639         }
01640 
01642 
01647         template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) const
01648         {
01649          #if __ITODEBUG
01650             if (m_dims != 2)
01651             {
01652                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01653             }
01654             else if ((x >= m_size[1]) || (y >= m_size[0]) )
01655             {
01656                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01657             }
01658          #endif           
01659                return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x);
01660         }
01661 
01663 
01668         template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x)
01669         {
01670          #if __ITODEBUG
01671             if (m_dims != 2)
01672             {
01673                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01674             }          
01675             else if (((size_t)x >= m_size[1]) || ((size_t)y >= m_size[0]) )
01676             {
01677                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01678             }
01679             
01680          #endif
01681                return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x);
01682         }
01683 
01685 
01691         template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) const
01692         {
01693          #if __ITODEBUG
01694             if (m_dims != 3)
01695             {
01696                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01697             }
01698             else if (((size_t)x >= m_size[2]) || ((size_t)y >= m_size[1]) || (((size_t)z + m_roi[0]) >= (m_roi[0] + m_size[0])))
01699             {
01700                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01701             }
01702          #endif
01703             
01704                return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x);
01705         }
01706 
01708 
01714         template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x)
01715         {
01716          #if __ITODEBUG
01717             if (m_dims != 3)
01718             {
01719                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01720             }
01721             else if (((size_t)x >= m_size[2]) || ((size_t)y >= m_size[1]) || (((size_t)z + m_roi[0]) >= (m_roi[0] + m_size[0])))
01722             {
01723                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01724             }
01725          #endif
01726             return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x);
01727         }
01728 
01730 
01735         template<typename _Tp> _Tp& at(const unsigned int *idx) const //idx is in virtual order 
01736         {
01737             size_t matNum = 0;
01738 
01739             matIdxToNum(idx, &matNum);
01740 
01741                return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]);
01742         }
01743 
01745 
01750         template<typename _Tp> _Tp& at(const unsigned int *idx) //idx is in virtual order 
01751         {
01752             size_t matNum = 0;
01753 
01754             matIdxToNum(idx, &matNum);
01755 
01756                return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]);
01757         }
01758 
01759         DataObject at(const ito::Range rowRange, const ito::Range colRange);     
01760         DataObject at(ito::Range *ranges);                                       
01762 
01763 
01769         uchar* rowPtr(const size_t matNum, const int y)
01770         {
01771             size_t matIndex = seekMat(matNum);
01772             return ((cv::Mat*)m_data[matIndex])->ptr(y);
01773         }
01774 
01776 
01782         const uchar* rowPtr(const size_t matNum, const int y) const
01783         {
01784             size_t matIndex = seekMat(matNum);
01785             return ((cv::Mat*)m_data[matIndex])->ptr(y);
01786         }
01787 
01788         DataObject row(const int selRow);
01789         DataObject col(const int selCol);
01790         //DataObject diag(void);
01791 
01792         // ROI
01793         DataObject & adjustROI(const int dtop, const int dbottom, const int dleft, const int dright);   
01794         DataObject & adjustROI(const unsigned char dims, const int *lims);                              
01795         RetVal locateROI(int *wholeSizes, int *offsets);                              
01796         RetVal locateROI(int *lims);                                                  
01797         template<typename _Tp> RetVal copyFromData2D(const _Tp* src, const size_t sizeX, const size_t sizeY);        
01798         template<typename _Tp> RetVal copyFromData2D(const _Tp *src, const size_t sizeX, const size_t sizeY, const int x0, const int y0, const size_t width, const size_t height);       
01799         template<typename _Tp> RetVal checkType(const _Tp *src);    //compares type of elements in this data objects and type of given argument (doc in source)
01800 
01801         //
01802         template<typename T2> operator T2 ();  
01803 };
01804 
01805 
01806 //----------------------------------------------------------------------------------------------------------------------------------
01807 // functions for DataObject in namespace ITO, which are NOT member functions
01808 //----------------------------------------------------------------------------------------------------------------------------------
01809 DataObject abs(const DataObject &dObj);              
01810 DataObject arg(const DataObject &dObj);              
01811 DataObject real(const DataObject &dObj);             
01812 DataObject imag(const DataObject &dObj);             
01814 DataObject makeContinuous(const DataObject &dObj);   
01816 template<typename _Tp, typename _T2> RetVal CastFunc(const DataObject *dObj, DataObject *resObj, double alpha = 1.0, double beta = 0.0);
01817 
01818 //RetVal minMaxLoc(const DataObject &dObj, double *minVal, double *maxVal, size_t *minPos = NULL, size_t *maxPos = NULL);
01819 
01821 
01828 template<typename _Tp> _Tp numberConversion(ito::tDataType fromType, void *scalar)
01829 {
01830     _Tp retValue = 0;
01831 
01832     switch(fromType)
01833     {
01834     case ito::tUInt8:
01835         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint8*>(scalar)));
01836         break;
01837     case ito::tInt8:
01838         retValue = cv::saturate_cast<_Tp>(*(static_cast<int8*>(scalar)));
01839         break;
01840     case ito::tUInt16:
01841         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint16*>(scalar)));
01842         break;
01843     case ito::tInt16:
01844         retValue = cv::saturate_cast<_Tp>(*(static_cast<int16*>(scalar)));
01845         break;
01846     case ito::tUInt32:
01847         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint32*>(scalar)));
01848         break;
01849     case ito::tInt32:
01850         retValue = cv::saturate_cast<_Tp>(*(static_cast<int32*>(scalar)));
01851         break;
01852     case ito::tFloat32:
01853         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float32*>(scalar)));
01854         break;
01855     case ito::tFloat64:
01856         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float64*>(scalar)));
01857         break;
01858     case ito::tComplex64:
01859         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex64*>(scalar)));
01860         break;
01861     case ito::tComplex128:
01862         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex128*>(scalar)));
01863         break;
01864     default:
01865         cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01866         retValue = 0;
01867     }
01868 
01869     return retValue;
01870 };
01871 
01872 
01873 
01874 //----------------------------------------------------------------------------------------------------------------------------------
01875 // cout
01876 //----------------------------------------------------------------------------------------------------------------------------------
01877 template<typename _Tp> static std::ostream& coutFunc(std::ostream& out, const DataObject& dObj)
01878 {
01879     //cv::Mat_<_Tp> *cvMat = NULL;
01880     size_t numMats = dObj.calcNumMats();
01881     size_t tMat = 0;
01882 
01883     std::cout << "Array(";
01884 
01885     for (size_t nMat = 0; nMat < numMats; nMat++)
01886     {
01887         tMat = dObj.seekMat(nMat, numMats);
01888         std::cout <<  tMat + 1 << "->(";
01889 
01890 //#ifndef linux
01891       
01892             std::cout << cv::format( (*((cv::Mat_<_Tp> *)((dObj.get_mdata())[tMat]))) , "numpy" ) << std::endl << std::endl;        
01893 //#endif
01894 
01895         std::cout << ")" << "\n" << std::endl;
01896     }
01897     std::cout << ")" << "\n" << std::endl;
01898     return out;
01899 
01900 }
01901 
01902 typedef std::ostream& (*tCoutFunc)(std::ostream& out, const DataObject& dObj);
01903 
01904 static tCoutFunc fListCout[] =
01905 {
01906    coutFunc<int8>,
01907    coutFunc<uint8>,
01908    coutFunc<int16>,
01909    coutFunc<uint16>,
01910    coutFunc<int32>,
01911    coutFunc<uint32>,
01912    coutFunc<ito::float32>,
01913    coutFunc<ito::float64>,
01914    coutFunc<ito::complex64>,
01915    coutFunc<ito::complex128>
01916 };
01917 
01918 static inline std::ostream& operator << (std::ostream& out, const DataObject& dObj)
01919 {
01920    return fListCout[dObj.getType()](out, dObj);
01921 }
01922 
01924 
01931 static ito::tDataType convertCmplxTypeToRealType(ito::tDataType cmplxType)
01932 {
01933     switch(cmplxType)
01934     {
01935         case ito::tInt8:
01936         case ito::tUInt8:
01937         case ito::tInt16:
01938         case ito::tUInt16:
01939         case ito::tInt32:
01940         case ito::tUInt32:
01941         case ito::tFloat32:
01942         case ito::tFloat64:
01943             return cmplxType;
01944         case ito::tComplex64:
01945             return ito::tFloat32;
01946         case ito::tComplex128:
01947             return ito::tFloat64;
01948     }
01949 
01950     cv::error(cv::Exception(CV_StsAssert, "Input data type unknown", "", __FILE__, __LINE__));
01951     return ito::tInt8;
01952 }
01953 
01955 
01963 template<typename _Tp> static inline ito::tDataType getDataType(const _Tp* /*src*/)
01964 {
01965     cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01966     return ito::tInt8;
01967 }
01968 
01969 template<> inline ito::tDataType getDataType(const uint8* /*src*/)      { return ito::tUInt8; }
01970 template<> inline ito::tDataType getDataType(const int8* /*src*/)       { return ito::tInt8; }
01971 template<> inline ito::tDataType getDataType(const uint16* /*src*/)     { return ito::tUInt16; }
01972 template<> inline ito::tDataType getDataType(const int16* /*src*/)      { return ito::tInt16; }
01973 template<> inline ito::tDataType getDataType(const uint32* /*src*/)     { return ito::tUInt32; }
01974 template<> inline ito::tDataType getDataType(const int32* /*src*/)      { return ito::tInt32; }
01975 template<> inline ito::tDataType getDataType(const float32* /*src*/)    { return ito::tFloat32; }
01976 template<> inline ito::tDataType getDataType(const float64* /*src*/)    { return ito::tFloat64; }
01977 template<> inline ito::tDataType getDataType(const complex64* /*src*/)  { return ito::tComplex64; }
01978 template<> inline ito::tDataType getDataType(const complex128* /*src*/) { return ito::tComplex128; }
01979 
01980 
01982 
01991 template<typename _Tp> static inline ito::tDataType getDataType2()
01992 {
01993     cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01994     return ito::tInt8;
01995 }
01996 
01997 template<> inline ito::tDataType getDataType2<uint8*>()      { return ito::tUInt8; }
01998 template<> inline ito::tDataType getDataType2<int8*>()       { return ito::tInt8; }
01999 template<> inline ito::tDataType getDataType2<uint16*>()     { return ito::tUInt16; }
02000 template<> inline ito::tDataType getDataType2<int16*>()      { return ito::tInt16; }
02001 template<> inline ito::tDataType getDataType2<uint32*>()     { return ito::tUInt32; }
02002 template<> inline ito::tDataType getDataType2<int32*>()      { return ito::tInt32; }
02003 template<> inline ito::tDataType getDataType2<float32*>()    { return ito::tFloat32; }
02004 template<> inline ito::tDataType getDataType2<float64*>()    { return ito::tFloat64; }
02005 template<> inline ito::tDataType getDataType2<complex64*>()  { return ito::tComplex64; }
02006 template<> inline ito::tDataType getDataType2<complex128*>() { return ito::tComplex128; }
02007 
02008 
02010 
02020 template<typename _Tp> static inline bool isZeroValue(_Tp v, _Tp /*epsilon*/)
02021 {
02022     return v == 0;
02023 }
02024 template<> inline bool isZeroValue(float32 v, float32 epsilon)
02025 {
02026     return v >= epsilon ? false : (v <= -epsilon ? false : true);
02027 }
02028 template<> inline bool isZeroValue(float64 v, float64 epsilon)
02029 {
02030     return v >= epsilon ? false : (v <= -epsilon ? false : true);
02031 }
02032 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon)
02033 {
02034     return isZeroValue<ito::float32>(v.real(),epsilon.real()) && isZeroValue<ito::float32>(v.imag(),epsilon.real());
02035 }
02036 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon)
02037 {
02038     return isZeroValue<ito::float64>(v.real(),epsilon.real()) && isZeroValue<ito::float64>(v.imag(),epsilon.real());
02039 }
02040 
02041 
02042 
02043 
02044 
02045 //----------------------------------------------------------------------------------------------------------------------------------
02046 // friend functions to access private members of DataObject
02047 //----------------------------------------------------------------------------------------------------------------------------------
02048 } //namespace ito
02049 
02050 #endif //__DATAOBJH
02051 
02052 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends