itom 1.3.0
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 "defines.h"
00032 
00033 //#include <crtdbg.h>
00034 #include <cstdlib>
00035 #include <iostream>
00036 #include <complex>
00037 #include <limits>
00038 #include <string>
00039 
00040 #if !linux
00041     #pragma warning(disable:4996)
00042 #endif
00043 
00044 #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
00045 
00046 #include "opencv/cv.h"
00047 #include "opencv2/core/core.hpp"
00048 
00049 #include "../common/sharedStructures.h"
00050 #include "../common/color.h"
00051 
00052 #include "readWriteLock.h"
00053 
00054 
00055 
00056 namespace cv 
00057 {
00058    template<> inline ito::float32 saturate_cast<ito::float32>( ito::float64 v)
00059    {
00060        //return (float32)v;
00061        if(cvIsInf(v)) return std::numeric_limits<ito::float32>::infinity();
00062        if(cvIsNaN(v)) return std::numeric_limits<ito::float32>::quiet_NaN();
00063        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() )));
00064    }
00065 
00066    template<> inline ito::float64 saturate_cast<ito::float64>( ito::float32 v)
00067    {
00068        //return (float64)v;
00069        if(cvIsInf(v)) return std::numeric_limits<ito::float64>::infinity();
00070        if(cvIsNaN(v)) return std::numeric_limits<ito::float64>::quiet_NaN();
00071        return static_cast<ito::float64>(v);
00072    }
00073 
00074    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; }
00075    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; }
00076    
00077    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; }
00078 //   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; }
00079  
00080    template<> inline ito::complex64 saturate_cast(ito::uint8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00081    template<> inline ito::complex64 saturate_cast(ito::int8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00082    template<> inline ito::complex64 saturate_cast(ito::uint16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00083    template<> inline ito::complex64 saturate_cast(ito::int16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00084    template<> inline ito::complex64 saturate_cast(ito::uint32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00085    template<> inline ito::complex64 saturate_cast(ito::int32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); }
00086    template<> inline ito::complex64 saturate_cast(ito::float32 v){ return ito::complex64(v,0.0); }
00087    template<> inline ito::complex64 saturate_cast(ito::float64 v){ return ito::complex64(saturate_cast<ito::float32>(v),0.0); }
00088    template<> inline ito::complex64 saturate_cast(ito::complex64 v){ return v; }
00089    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())); }
00090 
00091    template<> inline ito::complex128 saturate_cast(ito::uint8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00092    template<> inline ito::complex128 saturate_cast(ito::int8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00093    template<> inline ito::complex128 saturate_cast(ito::uint16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00094    template<> inline ito::complex128 saturate_cast(ito::int16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00095    template<> inline ito::complex128 saturate_cast(ito::uint32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00096    template<> inline ito::complex128 saturate_cast(ito::int32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); }
00097    template<> inline ito::complex128 saturate_cast(ito::float32 v){ return ito::complex128(saturate_cast<ito::float64>(v),0.0); }
00098    template<> inline ito::complex128 saturate_cast(ito::float64 v){ return ito::complex128(v,0.0); }
00099    template<> inline ito::complex128 saturate_cast(ito::complex64 v){ return ito::complex128(saturate_cast<ito::float64>(v.real()),saturate_cast<ito::float64>(v.imag())); }
00100    template<> inline ito::complex128 saturate_cast(ito::complex128 v){ return v; }
00101    
00102 // template<> inline ito::Rgba32 saturate_cast(ito::int8 v) {return ito::Rgba32(saturate_cast<ito::uint8>(v));}
00103    template<> inline ito::Rgba32 saturate_cast(ito::uint8 v) {return ito::Rgba32(v);}
00104    template<> inline ito::Rgba32 saturate_cast(ito::uint16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));}
00105 // template<> inline ito::Rgba32 saturate_cast(ito::int16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));}
00106    template<> inline ito::Rgba32 saturate_cast(ito::uint32 v)
00107    {
00108        return ito::Rgba32::fromUnsignedLong(v);
00109    }
00110    template<> inline ito::Rgba32 saturate_cast(ito::int32 v)
00111    {
00112        ito::Rgba32 temp;
00113        temp.rgba = static_cast<ito::uint32>(v);
00114        return temp;
00115    }
00116    template<> inline ito::Rgba32 saturate_cast(ito::float32 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));}
00117    template<> inline ito::Rgba32 saturate_cast(ito::float64 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));}
00118    template<> inline ito::Rgba32 saturate_cast(ito::Rgba32 v){return v;}
00119 
00120    template<> inline ito::Rgba32 saturate_cast(ito::int8 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from int8 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); }
00121    template<> inline ito::Rgba32 saturate_cast(ito::int16 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from int16 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); }
00122    template<> inline ito::Rgba32 saturate_cast(ito::complex128 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from complex128 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); }
00123    template<> inline ito::Rgba32 saturate_cast(ito::complex64 /*v*/) {  cv::error(cv::Exception(CV_StsAssert, "Cast from complex64 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); }
00124 
00125    template<> inline ito::uint8 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint8>(v.gray());};
00126    //template<> inline ito::int16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::int16>(v.gray());};
00127    template<> inline ito::uint16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint16>(v.gray());};
00128    template<> inline ito::uint32 saturate_cast(ito::Rgba32 v){return v.argb();};
00129    template<> inline ito::int32 saturate_cast(ito::Rgba32 v){return (ito::int32)(v.argb());};
00130    template<> inline ito::float32 saturate_cast(ito::Rgba32 v){return v.gray();};
00131    template<> inline ito::float64 saturate_cast(ito::Rgba32 v){return (ito::float64)v.gray();};
00132 
00133 
00134     template<> class DataType<ito::Rgba32>
00135     {
00136         public:
00137         typedef ito::Rgba32 value_type;
00138         typedef ito::uint8 channel_type;
00139         typedef Vec<channel_type, 4> work_type; 
00140         typedef value_type vec_type;
00141         enum 
00142         {
00143             generic_type = 0, 
00144             depth = cv::DataDepth<channel_type>::value, 
00145             channels = 4,
00146             fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt,
00147             type = CV_MAKETYPE(depth, channels)
00148         };
00149     };
00150 
00151     template<> class DataType<ito::RedChannel>
00152     {
00153         public:
00154         typedef ito::RedChannel value_type;
00155         typedef ito::uint8 channel_type;
00156         typedef Vec<channel_type, 4> work_type; 
00157         typedef value_type vec_type;
00158         enum 
00159         {
00160             generic_type = 0, 
00161             depth = cv::DataDepth<channel_type>::value, 
00162             channels = 4,
00163             fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt,
00164             type = CV_MAKETYPE(depth, channels)
00165         };
00166     };
00167 
00168     template<> class DataType<ito::GreenChannel>
00169     {
00170         public:
00171         typedef ito::GreenChannel value_type;
00172         typedef ito::uint8 channel_type;
00173         typedef Vec<channel_type, 4> work_type; 
00174         typedef value_type vec_type;
00175         enum 
00176         {
00177             generic_type = 0, 
00178             depth = cv::DataDepth<channel_type>::value, 
00179             channels = 4,
00180             fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt,
00181             type = CV_MAKETYPE(depth, channels)
00182         };
00183     };
00184 
00185     template<> class DataType<ito::BlueChannel>
00186     {
00187         public:
00188         typedef ito::BlueChannel value_type;
00189         typedef ito::uint8 channel_type;
00190         typedef Vec<channel_type, 4> work_type; 
00191         typedef value_type vec_type;
00192         enum 
00193         {
00194             generic_type = 0, 
00195             depth = cv::DataDepth<channel_type>::value, 
00196             channels = 4,
00197             fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt,
00198             type = CV_MAKETYPE(depth, channels)
00199         };
00200     };
00201 
00202     template<> class DataType<ito::AlphaChannel>
00203     {
00204         public:
00205         typedef ito::AlphaChannel value_type;
00206         typedef ito::uint8 channel_type;
00207         typedef Vec<channel_type, 4> work_type; 
00208         typedef value_type vec_type;
00209         enum 
00210         {
00211             generic_type = 0, 
00212             depth = cv::DataDepth<channel_type>::value, 
00213             channels = 4,
00214             fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt,
00215             type = CV_MAKETYPE(depth, channels)
00216         };
00217     };
00218 
00219 
00220 } // namespace cv
00221 
00222 namespace ito {
00223 
00224 #define __ITODEBUG 1
00225 
00226 class DObjIterator;  // Forward declaration
00227 class DataObject;
00228 class Range;
00229 struct Scalar;
00230 class DataObjectTags;
00231 class DataObjectTagType;
00232 class DataObjectTagsPrivate;
00233 
00234 
00236 
00244 template<typename _Tp> static inline ito::tDataType getDataType(const _Tp* /*src*/)
00245 {
00246     cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
00247     return ito::tInt8;
00248 }
00249 
00250 template<> inline ito::tDataType getDataType(const uint8* /*src*/)      { return ito::tUInt8; }
00251 template<> inline ito::tDataType getDataType(const int8* /*src*/)       { return ito::tInt8; }
00252 template<> inline ito::tDataType getDataType(const uint16* /*src*/)     { return ito::tUInt16; }
00253 template<> inline ito::tDataType getDataType(const int16* /*src*/)      { return ito::tInt16; }
00254 template<> inline ito::tDataType getDataType(const uint32* /*src*/)     { return ito::tUInt32; }
00255 template<> inline ito::tDataType getDataType(const int32* /*src*/)      { return ito::tInt32; }
00256 template<> inline ito::tDataType getDataType(const float32* /*src*/)    { return ito::tFloat32; }
00257 template<> inline ito::tDataType getDataType(const float64* /*src*/)    { return ito::tFloat64; }
00258 template<> inline ito::tDataType getDataType(const complex64* /*src*/)  { return ito::tComplex64; }
00259 template<> inline ito::tDataType getDataType(const complex128* /*src*/) { return ito::tComplex128; }
00260 template<> inline ito::tDataType getDataType(const Rgba32* /*src*/) { return ito::tRGBA32; }
00261 
00262 //----------------------------------------------------------------------------------------------------------------------------------
00267 class DATAOBJ_EXPORT Range
00268 {
00269     public:
00270         Range() : start(0), end(0) {}                           
00271         Range(int _start, int _end) { _start < _end ? (end = _end, start = _start) : (start = _end, end = _start); }  
00272         inline unsigned int size() const { return end - start; }
00273         inline bool empty() const { return (start == end); }    
00274         static Range all() { return Range(INT_MIN, INT_MAX); }  
00276         int start;                                               
00277         int end;                                                 
00278 };
00279 
00280 //----------------------------------------------------------------------------------------------------------------------------------
00281 class DATAOBJ_EXPORT DataObjectTagType
00282 {
00283     public:
00284         enum tTagType
00285         {
00286             typeInvalid     = 0x000000,
00287             typeDouble      = 0x000008,
00288             typeString      = 0x000020
00289         };
00290 
00291     private:
00292         double m_dVal;
00293         tTagType m_type; 
00294         ByteArray m_strValue;
00295 
00296     public:
00298         DataObjectTagType() : m_dVal(0), m_strValue(""), m_type(DataObjectTagType::typeInvalid){};
00299         DataObjectTagType(double dVal) : m_dVal(dVal), m_strValue(""), m_type(DataObjectTagType::typeDouble){};
00300         DataObjectTagType(const std::string &str) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ m_strValue = str.data(); };
00301         DataObjectTagType(const ByteArray &str) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ m_strValue = str; };
00302         DataObjectTagType(const char* cVal) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ cVal == NULL ?  m_strValue = "" : m_strValue = cVal;};
00304         DataObjectTagType(const DataObjectTagType& a) : m_dVal(a.m_dVal), m_type(a.m_type), m_strValue(a.m_strValue) {};
00305 
00306         DataObjectTagType & operator = (const DataObjectTagType &rhs)
00307         {
00308             this->m_dVal = rhs.m_dVal;
00309             this->m_strValue = rhs.m_strValue;
00310             this->m_type = rhs.m_type;
00311 
00312             return *this;
00313         }
00314 
00315         inline int getType(void) const {return m_type;};
00316 
00317         inline bool isValid(void) const { return (m_type == DataObjectTagType::typeInvalid) ? false: true;};
00318 
00324         inline double getVal_ToDouble(void)
00325         {
00326             if(m_type == DataObjectTagType::typeInvalid)
00327             {
00328                 return std::numeric_limits<double>::quiet_NaN();
00329             }
00330             else if(m_type == DataObjectTagType::typeDouble)
00331             {
00332                 return m_dVal;
00333             }
00334             else
00335             {
00336                 double dVal = std::numeric_limits<double>::quiet_NaN();
00337                 //dVal = atof(m_strValue.c_str()); //sometimes the result of that line has been arbitrary, therefore this conversion should fail.
00338                 return dVal;
00339             }
00340         }
00341 
00347         inline ByteArray getVal_ToString(void)
00348         {
00349             if(m_type == DataObjectTagType::typeInvalid)
00350             {
00351                 return "";
00352             }
00353             else if(m_type == DataObjectTagType::typeString)
00354             {
00355                 return m_strValue;
00356             }
00357             else
00358             {
00359                 if (cvIsNaN(m_dVal)) return "NaN";
00360                 if (cvIsInf(m_dVal)) return "Inf";
00361                 /*if(m_dVal == std::numeric_limits<double>::quiet_NaN()) return std::string("NaN");
00362                 if(m_dVal == std::numeric_limits<double>::signaling_NaN()) return std::string("NaN");
00363                 if(m_dVal == std::numeric_limits<double>::infinity()) return std::string("Inf");*/
00364 
00365                 std::ostringstream strs;
00366                 strs << m_dVal;
00367                 ByteArray ba(strs.str().data());
00368 
00369                 return ba;
00370             }
00371         }
00372 };
00373 
00374 //----------------------------------------------------------------------------------------------------------------------------------
00383 //class DATAOBJ_EXPORT DataObjectTags
00384 //{
00385 //private:
00386 //    DataObjectTagsPrivate *d;
00387 //
00388 //    friend class DataObject;
00389 //
00390 //
00391 //public:
00392 //    //!< Constructor
00393 //    DataObjectTags(unsigned int totalAxisNum);
00394 //
00395 //    //!< Destructor
00396 //    ~DataObjectTags();
00397 //
00398 //    //!< Copy constructor
00399 //    DataObjectTags(const DataObjectTags& copyConstr);
00400 //};
00401 
00402 //----------------------------------------------------------------------------------------------------------------------------------
00403 
00404 class DATAOBJ_EXPORT DObjConstIterator
00405 {
00406 public:
00407      
00409     DObjConstIterator();
00411     DObjConstIterator(const DataObject* _dObj, int pos = 0);
00413     DObjConstIterator(const DObjConstIterator& it);
00414     
00416     DObjConstIterator& operator = (const DObjConstIterator& it);
00418     uchar* operator *() const;
00420     uchar* operator [](int i) const;
00421     
00423     DObjConstIterator& operator += (int ofs);
00425     DObjConstIterator& operator -= (int ofs);
00427     DObjConstIterator& operator --();
00429     DObjConstIterator operator --(int);
00431     DObjConstIterator& operator ++();
00433     DObjConstIterator operator ++(int);
00434 
00435     bool operator == (const DObjConstIterator& dObjIt);
00436     bool operator != (const DObjConstIterator& dObjIt);
00437     bool operator < (const DObjConstIterator& dObjIt);
00438     bool operator > (const DObjConstIterator& dObjIt);
00439     bool operator <= (const DObjConstIterator& dObjIt);
00440     bool operator >= (const DObjConstIterator& dObjIt);
00441 
00442 protected:
00443     void seekAbs(int ofs);
00444     void seekRel(int ofs);
00445     
00446     const DataObject* dObj;
00447     bool   planeContinuous;
00448     int elemSize;
00449     uchar* ptr;
00450     uchar* sliceStart;
00451     uchar* sliceEnd;
00452     int plane;
00453 };
00454 
00455 //----------------------------------------------------------------------------------------------------------------------------------
00456 class DATAOBJ_EXPORT DObjIterator : public DObjConstIterator
00457 {
00458 public:
00459      
00461     DObjIterator();
00463     DObjIterator(DataObject* _dObj, int pos = 0);
00465     DObjIterator(const DObjIterator& it);
00466     
00468     DObjIterator& operator = (const DObjIterator& it);
00470     uchar* operator *();
00472     uchar* operator [](int i);
00473     
00475     DObjIterator& operator += (int ofs);
00477     DObjIterator& operator -= (int ofs);
00479     DObjIterator& operator --();
00481     DObjIterator operator --(int);
00483     DObjIterator& operator ++();
00485     DObjIterator operator ++(int);
00486 };
00487 
00488 //----------------------------------------------------------------------------------------------------------------------------------
00489 class DATAOBJ_EXPORT DataObject
00490 {
00491     private:
00492 
00494 
00508         //length(sizes) == length(steps)
00509         void createHeader(const unsigned char dimensions, const int *sizes, const int *steps, const int elemSize)
00510         {
00511             if(dimensions == 1)
00512             {
00513                 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__));
00514             }
00515 
00516             m_dims = dimensions;
00517 
00518             if(dimensions > 0)
00519             {
00520                 if (m_roi.m_p)
00521                 {
00522                     if (*(m_roi.m_p-1) != dimensions)
00523                     {
00524                         delete[] (m_roi.m_p - 1);
00525 
00526                         m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00527                         m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1;
00528                         m_osize.m_p[-1] = dimensions;
00529                         m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1;
00530                         m_size.m_p[-1] = dimensions;
00531                         m_roi.m_p = m_roi.m_p + 1;
00532                         m_roi.m_p[-1] = dimensions;
00533                     }
00534                 }
00535                 else
00536                 {
00537                     m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00538                     m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1;
00539                     m_osize.m_p[-1] = dimensions;
00540                     m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1;
00541                     m_size.m_p[-1] = dimensions;
00542                     m_roi.m_p = m_roi.m_p + 1;
00543                     m_roi.m_p[-1] = dimensions;
00544                 }
00545 
00546                 for (uchar n = 0 ; n < dimensions ; n++)
00547                 {
00548                     m_size.m_p[n] = sizes[n];
00549                     m_roi.m_p[n] = 0;
00550 
00551                     if(steps == NULL || n == 0)
00552                     {
00553                         m_osize.m_p[n] = sizes[n];
00554                     }
00555                     else if(n == dimensions - 1) //last element
00556                     {
00557                         if (elemSize == 0)
00558                             cv::Exception(CV_StsAssert, "elemSize is zero", "", __FILE__, __LINE__);
00559                         m_osize.m_p[n] = steps[n-1] / elemSize;
00560                     }
00561                     else /*if(n < dimensions -1)*/
00562                     {
00563                         if (steps[n] == 0)
00564                             cv::Exception(CV_StsAssert, "step size is zero", "", __FILE__, __LINE__);
00565                         m_osize.m_p[n] = steps[n - 1] / steps[n];
00566                     }
00567                 }
00568             }
00569         }
00570 
00572 
00585         void createHeaderWithROI(const unsigned char dimensions, const int *sizes, const int *osizes = NULL, const int *roi = NULL)
00586         {
00587             if(dimensions == 1)
00588             {
00589                 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__));
00590             }
00591 
00592             m_dims = dimensions;
00593 
00594             if(dimensions > 0)
00595             {
00596 
00597                 if (m_roi.m_p)
00598                 {
00599                     if (*(m_roi.m_p-1) != dimensions)
00600                     {
00601                         delete[] (m_roi.m_p-1);
00602 
00603                         m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00604                         m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1;
00605                         m_osize.m_p[-1] = dimensions;
00606                         m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1;
00607                         m_size.m_p[-1] = dimensions;
00608                         m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one
00609                         m_roi.m_p[-1] = dimensions;
00610                     }
00611                 }
00612                 else
00613                 {
00614                     m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)];
00615                     m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1;
00616                     m_osize.m_p[-1] = dimensions;
00617                     m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1;
00618                     m_size.m_p[-1] = dimensions;
00619                     m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one
00620                     m_roi.m_p[-1] = dimensions;
00621                 }
00622 
00623                 for (uchar n = 0; n < dimensions; n++)
00624                 {
00625                     m_size.m_p[n] = sizes[n];
00626 
00627                     if (osizes)
00628                     {
00629                         m_osize.m_p[n] = osizes[n];
00630                     }
00631                     else
00632                     {
00633                         m_osize.m_p[n] = sizes[n];
00634                     }
00635 
00636                     if (roi)
00637                     {
00638                         m_roi.m_p[n] = roi[n];
00639                     }
00640                     else
00641                     {
00642                         m_roi.m_p[n] = 0;
00643                     }
00644                 }
00645             }
00646         }
00647 
00648         void create(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous, const uchar* continuousDataPtr = NULL, const int* steps = NULL);  
00649         void create(const unsigned char dimensions, const int *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes);
00650 
00651         void freeData(void);     
00652         void secureFreeData(void); 
00655         //----------------------------------------------------------------------------------------------------------------------------------
00656         ito::RetVal matNumToIdx(const int matNum, int *matIdx) const;
00657 
00659 
00667         inline ito::RetVal matIdxToNum(const unsigned int *matIdx, int *matNum) const
00668         {
00669            *matNum = 0;
00670            if (m_dims <= 2)
00671            {
00672                  return 0;
00673            }
00674 
00675            int planeSize = 1;
00676 
00677            for (int n = m_dims - 3; n >= 0; n--)
00678            {
00679         #if __ITODEBUG
00680                  if (((int)matIdx[n] + m_roi[n]) >= m_osize[n])
00681                  {
00682                     cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__));
00683                  }
00684         #endif
00685                  (*matNum) += ((int)matIdx[n] + m_roi[n]) * planeSize; //CAST_TODO
00686                  planeSize *= m_osize[n];
00687            }
00688 
00689            return 0;
00690         }
00691 
00692         struct DATAOBJ_EXPORT MSize
00693         {
00694             inline MSize() : m_p(NULL) {}
00695             inline int operator [] (const int dim) const
00696             {
00697                 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory
00698             };
00699             inline operator const int * () const { return m_p; }
00700             bool operator == (const MSize& sz) const
00701             {
00702                 if(m_p == NULL || sz.m_p == NULL)
00703                 {
00704                     return sz.m_p == m_p;
00705                 }
00706 
00707                 int d = m_p[-1], dsz = sz.m_p[-1];
00708                 if( d != dsz )
00709                     return false;
00710                 if( d == 2 )
00711                 {                    
00712                     return m_p[0] == sz.m_p[0] && m_p[1] == sz.m_p[1];            
00713                 }
00714 
00715                 for( int i = 0; i < d - 2; i++ )
00716                 {
00717                     if( m_p[i] != sz.m_p[i] )
00718                     {
00719                         return false;
00720                     }
00721                 }                
00722                 return (m_p[d - 2] == sz.m_p[d - 2]) && (m_p[d - 1] == sz.m_p[d - 1]);               
00723             }
00724 
00725             inline bool operator != (const MSize& sz) const { return !(*this == sz); }
00726 
00727             int *m_p;
00728         };
00729 
00730         struct DATAOBJ_EXPORT MROI
00731         {
00732             inline MROI() : m_p(NULL) {};
00733             inline int operator [] (const int dim) const
00734             {
00735                 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory
00736             }
00737 
00738             bool operator == (const MROI & rroi) const
00739             {
00740                 if(m_p == NULL || rroi.m_p == NULL)
00741                 {
00742                     return rroi.m_p == m_p;
00743                 }
00744 
00745                 if (m_p[-1] != rroi.m_p[-1])
00746                 {
00747                     return false;
00748                 }
00749 
00750                 int d = m_p[-1];
00751                 for (int n = 0; n < d - 2; n++)
00752                 {
00753                     if (m_p[n] != rroi.m_p[n])
00754                     {
00755                         return false;
00756                     }
00757                 }
00758 
00759                 return m_p[d - 2] == rroi.m_p[d - 2] && m_p[d - 1] == rroi.m_p[d - 1];
00760                 
00761             }
00762 
00763             int *m_p;
00764         };
00765 
00766         DataObject(const DataObject& dObj, bool transposed);    
00768         char    m_continuous;                        
00769         char    m_owndata;                           
00770         int     m_type;                              
00771         int     *m_pRefCount;                        
00772         int     m_dims;                              
00773         MSize   m_osize;                             
00774         MROI    m_roi;                               
00775         MSize   m_size;                              
00776         uchar  **m_data;                             
00777         ReadWriteLock      *m_objSharedDataLock;     
00778         DataObjectTagsPrivate *m_pDataObjectTags;    
00779         ReadWriteLock       m_objHeaderLock;         
00780         static const int m_sizeofs;
00781 
00782         int mdata_realloc(const int size);
00783         
00784         int mdata_size(void) const;
00785         
00786         int mdata_free();
00787 
00788         RetVal copyFromData2DInternal(const uchar* src, const int sizeOfElem, const int sizeX, const int sizeY);  
00789         RetVal copyFromData2DInternal(const uchar* src, const int sizeOfElem, const int sizeX, const int x0, const int y0, const int width, const int height);
00790         
00791 
00792         //low-level, templated methods
00793         //most low-level methods are marked "friend" such that they can access private members of their data object parameters
00794         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);
00795         template<typename _Tp> friend RetVal CreateFuncWithCVPlanes(DataObject *dObj, const unsigned char dimensions, const int *sizes, const cv::Mat* planes, const unsigned int nrOfPlanes);
00796         template<typename _Tp> friend RetVal FreeFunc(DataObject *dObj);
00797         template<typename _Tp> friend RetVal SecureFreeFunc(DataObject *dObj);
00798         template<typename _Tp> friend RetVal CopyToFunc(const DataObject &lhs, DataObject &rhs, unsigned char regionOnly);
00799         template<typename _Tp> friend RetVal ConvertToFunc(const DataObject &lhs, DataObject &rhs, const int type, const double alpha, const double beta);
00800         template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, const int *lims);
00801         template<typename _Tp> friend RetVal MinMaxLocFunc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos, int *maxPos);
00802         template<typename _Tp> friend RetVal AssignScalarFunc(const DataObject *src, const ito::tDataType type, const void *scalar);
00803         template<typename _Tp> friend RetVal MakeContinuousFunc(const DataObject &dObj, DataObject &resDObj);
00804         template<typename _Tp> friend RetVal EvaluateTransposeFlagFunc(DataObject *dObj);
00805         template<typename _Tp> friend RetVal CalcMinMaxValues(DataObject *lhs, double &result_min, double &result_max, const int cmplxSel = 0);
00806         template<typename _Tp> friend std::ostream& coutFunc(std::ostream& out, const DataObject& dObj);
00807 
00808         // more friends due to change of std::vector to int ** for m_data ...
00809         template<typename _Tp> friend RetVal GetRangeFunc(DataObject *dObj, const int dtop, const int dbottom, const int dleft, const int dright);
00810         template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, int dtop, int dbottom, int dleft, int dright);
00811 
00812     public:
00813         int seekMat(const int matNum, const int numMats) const;
00814         int seekMat(const int matNum) const;
00815         int calcNumMats(void) const;
00816 
00817         // TAGSPACEFUNCTIONS
00818 
00820         double getValueOffset() const;
00821 
00823         double getValueScale() const;
00824 
00826         const std::string getValueUnit() const;
00827 
00829         std::string getValueDescription() const;
00830 
00832         double getAxisOffset(const int axisNum) const;
00833         
00835         double getAxisScale(const int axisNum) const;
00836         
00838         const std::string getAxisUnit(const int axisNum, bool &validOperation) const;
00839         
00841         std::string getAxisDescription(const int axisNum, bool &validOperation) const;
00842         
00843         DataObjectTagType getTag(const std::string &key, bool &validOperation) const;
00844         
00845         bool getTagByIndex(const int tagNumber, std::string &key, DataObjectTagType &value) const;
00846         
00848         std::string getTagKey(const int tagNumber, bool &validOperation) const;
00849         
00851         int getTagListSize() const;
00852 
00854         int setValueUnit(const std::string &unit);
00855 
00857         int setValueDescription(const std::string &description);
00858 
00859         //inline lead to a linker error on MSVC when calling from several methods
00860         int setAxisOffset(const unsigned int axisNum, const double offset);
00861         int setAxisScale(const unsigned int axisNum, const double scale);
00862         int setAxisUnit(const unsigned int axisNum, const std::string &unit);
00863         int setAxisDescription(const unsigned int axisNum, const std::string &description);
00864         int setTag(const std::string &key, const DataObjectTagType &value);
00865         bool existTag(const std::string &key) const;
00866         bool deleteTag(const std::string &key);
00867         bool deleteAllTags();
00868         int addToProtocol(const std::string &value);
00869 
00870 
00881         inline double getPhysToPix(const unsigned int dim, const double phys, bool &isInsideImage) const
00882         {
00883             double tPx = 0.0;
00884             if(static_cast<int>(dim) >= m_dims)
00885             {
00886                 if(phys == 0.0)
00887                 {
00888                     isInsideImage = true;
00889                 }
00890                 else
00891                 {
00892                     isInsideImage = false;
00893                 }
00894                 return 0.0;
00895             }
00896 
00897             if(m_pDataObjectTags)
00898             {
00899                 tPx = (phys / getAxisScale(dim) + getAxisOffset(dim));
00900             }
00901             else
00902             {
00903                 tPx = phys;
00904             }
00905 
00906             if(tPx > getSize(dim) - 1)
00907             {
00908                 isInsideImage = false;
00909                 tPx = static_cast<double>(getSize(dim)- 1);
00910             }
00911             else if( tPx < 0)
00912             {
00913                 isInsideImage = false;
00914                 tPx = 0;
00915             }
00916             else
00917             {
00918                 isInsideImage = true;
00919             }
00920 
00921             return tPx;
00922         }
00923 
00927         inline int getPhysToPix2D(const double physY, double &tPxY, bool &isInsideImageY, const double physX, double &tPxX, bool &isInsideImageX) const
00928         {
00929             if(m_dims < 2)
00930             {           
00931                     tPxY = physY;
00932                     if(physY != 0.0)
00933                     {
00934                         isInsideImageY = false;
00935                     }
00936 
00937                     tPxX = physX / getAxisScale(0) + getAxisOffset(0); //m_pDataObjectTags->m_axisScales[0] + m_pDataObjectTags->m_axisOffsets[0];
00938 
00939                     if(tPxX > m_size[0] - 1)
00940                     {
00941                         isInsideImageX = false;
00942                         tPxX = static_cast<double>(m_size[0] - 1);
00943                     }                
00944             }
00945             else
00946             {             
00947                     if(m_pDataObjectTags)
00948                     {
00949                         tPxX = physX / getAxisScale(m_dims - 1) + getAxisOffset(m_dims - 1);
00950                         tPxY = physY / getAxisScale(m_dims - 2) + getAxisOffset(m_dims - 2);
00951                     }
00952                     else
00953                     {
00954                         tPxX = physX;
00955                         tPxY = physY;
00956                     }
00957 
00958                     if(tPxY > m_size[m_dims - 2] - 1)
00959                     {
00960                         isInsideImageY = false;
00961                         tPxY = static_cast<double>(m_size[m_dims - 2] - 1);
00962                     }
00963                     if(tPxX > m_size[m_dims - 1] - 1)
00964                     {
00965                         isInsideImageX = false;
00966                         tPxY = static_cast<double>(m_size[m_dims - 1] - 1);
00967                     }                
00968             }
00969 
00970             if(tPxX < 0)
00971             {
00972                 tPxX = 0;
00973                 isInsideImageX = false;
00974             }
00975             if(tPxY < 0)
00976             {
00977                 tPxY = 0;
00978                 isInsideImageY = false;
00979             }
00980             return 0;
00981         }
00982 
00992         inline double getPixToPhys(const unsigned int dim, const double pix, bool &isInsideImage) const
00993         {
00994             double tPhys = 0.0;
00995             if(static_cast<int>(dim) >= m_dims)
00996             {
00997                 if(pix == 0)
00998                 {
00999                     isInsideImage = true;
01000                 }
01001                 else
01002                 {
01003                     isInsideImage = false;
01004                 }
01005                 return 0.0;
01006             }
01007             if(m_pDataObjectTags)
01008             {
01009                 tPhys = (pix - getAxisOffset(dim)) * getAxisScale(dim);
01010             }
01011             else
01012             {
01013                 tPhys = pix;
01014             }
01015 
01016             if((pix > getSize(dim) - 1) || (pix < 0))
01017             {
01018                 isInsideImage = false;
01019             }
01020             else
01021             {
01022                 isInsideImage = true;
01023             }
01024 
01025             return tPhys;
01026         }
01027 
01041         RetVal setXYRotationalMatrix(double r11, double r12, double r13, double r21, double r22, double r23, double r31, double r32, double r33);
01042 
01056         RetVal getXYRotationalMatrix(double &r11, double &r12, double &r13, double &r21, double &r22, double &r23, double &r31, double &r32, double &r33) const;
01057 
01058         RetVal copyTagMapTo(DataObject &rhs) const;  
01059         RetVal copyAxisTagsTo(DataObject &rhs) const;  
01061         // END TAGSPACE
01062 
01064         inline int getDims(void) const { return m_dims; }
01065 
01067         inline int getType(void) const { return m_type; }
01068 
01070         inline char getContinuous(void) const { return m_continuous; }
01071 
01073         inline char getOwnData(void) const { return m_owndata; }
01074         
01076 
01080         inline int getTotal() const
01081         {
01082             int dims = getDims();
01083             int total = dims > 0 ? 1 : 0;
01084             for(int i = 0 ; i<dims ; i++)
01085             {
01086                 total *= getSize(i);
01087             }
01088             return total;
01089 
01090         }
01091 
01093 
01097         inline int getOriginalTotal() const
01098         {
01099             int dims = getDims();
01100             int total = dims > 0 ? 1 : 0;
01101             for(int i = 0 ; i<dims ; i++)
01102             {
01103                 total *= m_osize[i];
01104             }
01105             return total;
01106 
01107         }
01108 
01110 
01118         inline void lockRead()
01119         {
01120             m_objHeaderLock.lockRead();
01121             if(m_objSharedDataLock) m_objSharedDataLock->lockRead();
01122         }
01123 
01125 
01128         inline void lockWrite()
01129         {
01130             m_objHeaderLock.lockWrite();
01131             if(m_objSharedDataLock) m_objSharedDataLock->lockWrite();
01132         }
01133 
01135 
01138         inline void unlock()
01139         {
01140             if(m_objSharedDataLock) m_objSharedDataLock->unlock();
01141             m_objHeaderLock.unlock();
01142         }
01143         
01144         RetVal copyTo(DataObject &rhs, unsigned char regionOnly = 0);   
01145         RetVal convertTo(DataObject &rhs, const int type, const double alpha=1, const double beta=0 ) const;
01146         RetVal deepCopyPartial(DataObject &rhs);                         
01148         uchar ** get_mdata(void);
01149         uchar ** get_mdata(void) const;
01150 
01151         cv::Mat* getCvPlaneMat(const int planeIndex);
01152         const cv::Mat* getCvPlaneMat(const int planeIndex) const;
01153 
01155 
01158         inline MSize getSize(void) { return m_size; }
01159 
01161 
01164         inline const MSize getSize(void) const { return m_size; }
01165 
01167 
01171         int getSize(int index) const
01172         {
01173             if(index < 0 || index >= m_dims)
01174             {
01175                 return -1;
01176             }
01177             else
01178             {
01179                 return m_size[index];
01180             }
01181         }
01182 
01184 
01188         int getOriginalSize(int index) const
01189         {
01190             if(index < 0 || index >= m_dims)
01191             {
01192                 return -1;           
01193             }
01194             else
01195             {
01196                 return m_osize[index];
01197             }
01198         }
01199 
01201         DObjIterator begin();
01203         DObjIterator end();
01204 
01205         DObjConstIterator constBegin() const;
01206         DObjConstIterator constEnd() const;
01207 
01209 
01212         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) {}
01213 
01215 
01223         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)
01224         {
01225             int sizes[2] = {1, size};
01226             this->create(2, sizes, type, 1);
01227         }
01228 
01230 
01238         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)
01239         {
01240             int sizes[2] = {sizeY, sizeX};
01241             this->create(2, sizes, type, 1);
01242         }
01243 
01245 
01255         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)
01256         {
01257             int sizes[3] = {sizeZ, sizeY, sizeX};
01258             this->create(3, sizes, type, m_continuous);
01259         }
01260 
01262 
01276         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)
01277         {
01278             int sizes[3] = {sizeZ, sizeY, sizeX};
01279             this->create(3, sizes, type, m_continuous, continuousDataPtr, steps);
01280         }
01281 
01283 
01292         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)
01293         {
01294             this->create(dimensions, sizes, type, m_continuous);
01295         }
01296 
01298 
01311         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)
01312         {
01313             this->create(dimensions, sizes, type, m_continuous, continuousDataPtr, steps);
01314         }
01315 
01316         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)
01317         {
01318             //usually it is dangerous to say that m_owndata is 1 in this case, since we cannot be sure if the given planes are the owner of their data.
01319             //however, in this case, owndata is unimportant since the created dataObject is always not continuous, therefore owndata will never
01320             //be analyzed and the destructor of the dataObject never tries to delete the continuous data block. The underlying cv::Mats however still know
01321             //whether they can or can't delete their data.
01322             this->create(dimensions, sizes, type, planes, nrOfPlanes);
01323         }
01324 
01325         DataObject(const DataObject& copyConstr);    
01327 
01328 
01334         ~DataObject(void)
01335         {
01336             freeData();
01337         }
01338 
01340         DataObject & operator = (const cv::Mat &rhs);
01341         DataObject & operator = (const DataObject &rhs);
01342         DataObject & operator = (const int8 &value);          
01343         DataObject & operator = (const uint8 &value);         
01344         DataObject & operator = (const int16 &value);         
01345         DataObject & operator = (const uint16 &value);        
01346         DataObject & operator = (const int32 &value);         
01347         DataObject & operator = (const uint32 &value);        
01348         DataObject & operator = (const float32 &value);       
01349         DataObject & operator = (const float64 &value);       
01350         DataObject & operator = (const complex64 &value);     
01351         DataObject & operator = (const complex128 &value);    
01352         DataObject & operator = (const ito::Rgba32 &value);   
01355         DataObject & operator += (const DataObject &rhs);
01356         DataObject & operator += (const float64 &value);
01357 
01358         DataObject operator + (const DataObject &rhs);
01359         DataObject operator + (const float64 &value);
01360 
01361         DataObject & operator -= (const DataObject &rhs);
01362         DataObject & operator -= (const float64 &value);
01363 
01364         DataObject operator - (const DataObject &rhs);
01365         DataObject operator - (const float64 &value);
01366 
01367         DataObject & operator *= (const DataObject &rhs);
01368         DataObject & operator *= (const float64 &factor);
01369 
01370         DataObject operator * (const DataObject &rhs);
01371         DataObject operator * (const float64 &factor);
01372 
01373         // Comparison Operators
01374         DataObject operator < (DataObject &rhs);
01375         DataObject operator > (DataObject &rhs);
01376         DataObject operator <= (DataObject &rhs);
01377         DataObject operator >= (DataObject &rhs);
01378         DataObject operator == (DataObject &rhs);
01379         DataObject operator != (DataObject &rhs);
01380 
01381 
01382         // bitshift operators
01383         DataObject operator << (const unsigned int shiftbit);
01384         DataObject & operator <<= (const unsigned int shiftbit);
01385         DataObject operator >> (const unsigned int shiftbit);
01386         DataObject & operator >>= (const unsigned int shiftbit);
01387 
01388         // bitwise operators
01389         DataObject operator & (const DataObject & rhs);
01390         DataObject & operator &= (const DataObject & rhs);
01391         DataObject operator | (const DataObject & rhs);
01392         DataObject & operator |= (const DataObject & rhs);
01393         DataObject operator ^ (const DataObject & rhs);
01394         DataObject & operator ^= (const DataObject & rhs);
01395 
01396         // allocates matrix with zero values
01397         RetVal zeros(const int type);
01398         RetVal zeros(const int size, const int type);
01399         RetVal zeros(const int sizeY, const int sizeX, const int type);
01400         RetVal zeros(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0);
01401         RetVal zeros(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0);
01402 
01403         // allocates matrix with all values set to one
01404         RetVal ones(const int type);
01405         RetVal ones(const int size, const int type);
01406         RetVal ones(const int sizeY, const int sizeX, const int type);
01407         RetVal ones(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0);
01408         RetVal ones(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0);
01409 
01410         // allocates matrix with uniform distributed noise
01411         RetVal rand(const int type, const bool randMode = false);
01412         RetVal rand(const int size, const int type, const bool randMode = false);
01413         RetVal rand(const int sizeY, const int sizeX, const int type, const bool randMode = false);
01414         RetVal rand(const int sizeZ, const int sizeY, const int sizeX, const int type, const bool randMode, const unsigned char continuous = 0);
01415         RetVal rand(const unsigned char dimensions, const int *sizes, const int type, const bool randMode, const unsigned char continuous = 0);
01416 
01417         // allocates matrix with eye-matrix representation
01418         RetVal eye(const int type);
01419         RetVal eye(const int size, const int type);
01420 
01421         RetVal conj();
01422         DataObject adj() const;
01423         DataObject trans() const;
01424 
01425         //RetVal makeContinuous(void);
01426 
01427         DataObject mul(const DataObject &mat2, const double scale = 1.0);
01428         DataObject div(const DataObject &mat2, const double scale = 1.0);
01429         DataObject squeeze() const;
01430         int elemSize() const;
01431 
01433 
01438         template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) const
01439         {
01440          #if __ITODEBUG
01441             if (m_dims != 2)
01442             {
01443                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01444             }
01445             else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) )
01446             {
01447                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01448             }
01449          #endif           
01450                return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x);
01451         }
01452 
01454 
01459         template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x)
01460         {
01461          #if __ITODEBUG
01462             if (m_dims != 2)
01463             {
01464                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01465             }          
01466             else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) )
01467             {
01468                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01469             }
01470             
01471          #endif
01472                return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x);
01473         }
01474 
01476 
01482         template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) const
01483         {
01484          #if __ITODEBUG
01485             if (m_dims != 3)
01486             {
01487                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01488             }
01489             else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0])))
01490             {
01491                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01492             }
01493          #endif
01494             
01495                return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x);
01496         }
01497 
01499 
01505         template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x)
01506         {
01507          #if __ITODEBUG
01508             if (m_dims != 3)
01509             {
01510                cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__));
01511             }
01512             else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0])))
01513             {
01514                 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__));
01515             }
01516          #endif
01517             return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x);
01518         }
01519 
01521 
01526         template<typename _Tp> _Tp& at(const unsigned int *idx) const //idx is in virtual order 
01527         {
01528             int matNum = 0;
01529 
01530             matIdxToNum(idx, &matNum);
01531 
01532             return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]);
01533         }
01534 
01536 
01541         template<typename _Tp> _Tp& at(const unsigned int *idx) //idx is in virtual order 
01542         {
01543             int matNum = 0;
01544 
01545             matIdxToNum(idx, &matNum);
01546 
01547             return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]);
01548         }
01549 
01550         DataObject at(const ito::Range &rowRange, const ito::Range &colRange);     
01551         DataObject at(ito::Range *ranges);                                       
01553 
01554 
01560         uchar* rowPtr(const int matNum, const int y)
01561         {
01562             int matIndex = seekMat(matNum);
01563             return ((cv::Mat*)m_data[matIndex])->ptr(y);
01564         }
01565 
01567 
01573         const uchar* rowPtr(const int matNum, const int y) const
01574         {
01575             int matIndex = seekMat(matNum);
01576             return ((cv::Mat*)m_data[matIndex])->ptr(y);
01577         }
01578 
01579         DataObject row(const int selRow);
01580         DataObject col(const int selCol);
01581 
01582         DataObject toGray(const int destinationType = ito::tUInt8);
01583 
01584         // ROI
01585         DataObject & adjustROI(const int dtop, const int dbottom, const int dleft, const int dright);   
01586         DataObject & adjustROI(const unsigned char dims, const int *lims);                              
01587         RetVal locateROI(int *wholeSizes, int *offsets);                              
01588         RetVal locateROI(int *lims);                                                  
01590 
01591 
01606         template<typename _Tp> RetVal copyFromData2D(const _Tp* src, const int sizeX, const int sizeY) { return copyFromData2DInternal((const uchar*)src, sizeof(_Tp), sizeX, sizeY); }        // copies 2D continuous data into data object, data object must have correct size and type, otherwise an error is returned
01607 
01609 
01633         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) { return copyFromData2DInternal((const uchar*)src, sizeof(_Tp), sizeX, x0, y0, width, height); }      // copies 2D continuous data into data object, data object must have correct size and type, otherwise an error is returned
01634         
01635         //----------------------------------------------------------------------------------------------------------------------------------
01637         /*
01638             \param [in] src is any variable whose type is checked
01639             \return retOk if both types are equal, retError if they are not equal or if the type of src is unknown
01640         */
01641         template<typename _Tp> RetVal checkType(const _Tp *src)    //must be inline since function template!
01642         {
01643             try
01644             {
01645                 if(m_type == ito::getDataType(src))
01646                 {
01647                     return ito::retOk;
01648                 }
01649                 return RetVal(retError,0,"CheckType failed: types are not equal");
01650             }
01651             catch(cv::Exception /*&ex*/)
01652             {
01653                 return RetVal(retError,0,"Error during Type-Check. Type not templated");
01654             }
01655         }
01656 
01657         //
01658         template<typename T2> operator T2 ();  
01660         template<typename _Tp> RetVal linspace(const _Tp start, const _Tp end, const _Tp inc, const int transposed);
01661 
01662 };
01663 
01664 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::int8>(const ito::int8 /*start*/, const ito::int8 /*end*/, const ito::int8 /*inc*/, const int /*transposed*/);
01665 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::uint8>(const ito::uint8 /*start*/, const ito::uint8 /*end*/, const ito::uint8 /*inc*/, const int /*transposed*/);
01666 
01667 
01668 //----------------------------------------------------------------------------------------------------------------------------------
01669 // functions for DataObject in namespace ITO, which are NOT member functions
01670 //----------------------------------------------------------------------------------------------------------------------------------
01671 DataObject DATAOBJ_EXPORT abs(const DataObject &dObj);              
01672 DataObject DATAOBJ_EXPORT arg(const DataObject &dObj);              
01673 DataObject DATAOBJ_EXPORT real(const DataObject &dObj);             
01674 DataObject DATAOBJ_EXPORT imag(const DataObject &dObj);             
01676 DataObject DATAOBJ_EXPORT makeContinuous(const DataObject &dObj);   
01678 template<typename _Tp, typename _T2> RetVal CastFunc(const DataObject *dObj, DataObject *resObj, double alpha = 1.0, double beta = 0.0);
01679 
01680 //RetVal minMaxLoc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos = NULL, int *maxPos = NULL);
01681 
01683 
01690 template<typename _Tp> _Tp numberConversion(ito::tDataType fromType, void *scalar)
01691 {
01692     //_Tp retValue = 0;
01693     _Tp retValue;
01694 
01695     switch(fromType)
01696     {
01697     case ito::tUInt8:
01698         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint8*>(scalar)));
01699         break;
01700     case ito::tInt8:
01701         retValue = cv::saturate_cast<_Tp>(*(static_cast<int8*>(scalar)));
01702         break;
01703     case ito::tUInt16:
01704         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint16*>(scalar)));
01705         break;
01706     case ito::tInt16:
01707         retValue = cv::saturate_cast<_Tp>(*(static_cast<int16*>(scalar)));
01708         break;
01709     case ito::tUInt32:
01710         retValue = cv::saturate_cast<_Tp>(*(static_cast<uint32*>(scalar)));
01711         break;
01712     case ito::tInt32:
01713         retValue = cv::saturate_cast<_Tp>(*(static_cast<int32*>(scalar)));
01714         break;
01715     case ito::tFloat32:
01716         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float32*>(scalar)));
01717         break;
01718     case ito::tFloat64:
01719         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float64*>(scalar)));
01720         break;
01721     case ito::tComplex64:
01722         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex64*>(scalar)));
01723         break;
01724     case ito::tComplex128:
01725         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex128*>(scalar)));
01726         break;
01727     case ito::tRGBA32:
01728         retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::Rgba32*>(scalar)));
01729         break;
01730     default:
01731         cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01732         retValue = 0;
01733     }
01734 
01735     return retValue;
01736 };
01737 
01738 //template<> ito::Rgba32 numberConversion<ito::Rgba32>(ito::tDataType fromType, void *scalar)
01739 //{
01740 //    _Tp retValue = 0;
01741 //
01742 //    switch(fromType)
01743 //    {
01744 //    case ito::tUInt8:
01745 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint8*>(scalar)));
01746 //        break;
01747 //    case ito::tInt8:
01748 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int8*>(scalar)));
01749 //        break;
01750 //    case ito::tUInt16:
01751 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint16*>(scalar)));
01752 //        break;
01753 //    case ito::tInt16:
01754 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int16*>(scalar)));
01755 //        break;
01756 //    case ito::tUInt32:
01757 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint32*>(scalar)));
01758 //        break;
01759 //    case ito::tInt32:
01760 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int32*>(scalar)));
01761 //        break;
01762 //    case ito::tFloat32:
01763 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float32*>(scalar)));
01764 //        break;
01765 //    case ito::tFloat64:
01766 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float64*>(scalar)));
01767 //        break;
01768 //    case ito::tComplex64:
01769 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex64*>(scalar)));
01770 //        break;
01771 //    case ito::tComplex128:
01772 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex128*>(scalar)));
01773 //        break;
01774 //    case ito::tRGBA32:
01775 //        retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::Rgba32*>(scalar)));
01776 //        break;
01777 //    default:
01778 //        cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01779 //        retValue = 0;
01780 //    }
01781 //
01782 //    return retValue;
01783 //}
01784 
01785 //----------------------------------------------------------------------------------------------------------------------------------
01786 // cout
01787 //----------------------------------------------------------------------------------------------------------------------------------
01788 template<typename _Tp> static std::ostream& coutFunc(std::ostream& out, const DataObject& dObj)
01789 {
01790     //cv::Mat_<_Tp> *cvMat = NULL;
01791     int numMats = dObj.calcNumMats();
01792     int tMat = 0;
01793 
01794     if (dObj.getDims() == 0)
01795     {
01796         std::cout << "DataObject()\n" << std::endl;
01797     }
01798     else
01799     {
01800         std::cout << "DataObject(size=[" << dObj.getSize(0);
01801         for (int dim = 1; dim < dObj.getDims(); ++dim)
01802         {
01803             std::cout << "x" << dObj.getSize(dim);
01804         }
01805         std::cout << "]\n" << std::endl;
01806 
01807         int *idx = new int[dObj.getDims()];
01808          
01809 
01810         for (int nMat = 0; nMat < numMats; nMat++)
01811         {
01812             tMat = dObj.seekMat(nMat, numMats);
01813             //std::cout <<  tMat + 1 << "->(";
01814 
01815             dObj.matNumToIdx(tMat, idx);
01816             std::cout << "[";
01817             for (int i = 0; i < dObj.getDims() - 2; ++i)
01818             {
01819                 std::cout << idx[i] << ",";
01820             }
01821             std::cout << ":,:]->(";
01822 
01823             std::cout << cv::format( (*((cv::Mat_<_Tp> *)((dObj.get_mdata())[tMat]))) , "numpy" ) << std::endl << std::endl;        
01824 
01825             std::cout << ")" << "\n" << std::endl;
01826         }
01827 
01828         delete[] idx;
01829 
01830         std::cout << ")" << "\n" << std::endl;
01831     }
01832     return out;
01833 
01834 }
01835 
01836 typedef std::ostream& (*tCoutFunc)(std::ostream& out, const DataObject& dObj);
01837 
01838 static tCoutFunc fListCout[] =
01839 {
01840    coutFunc<int8>,
01841    coutFunc<uint8>,
01842    coutFunc<int16>,
01843    coutFunc<uint16>,
01844    coutFunc<int32>,
01845    coutFunc<uint32>,
01846    coutFunc<ito::float32>,
01847    coutFunc<ito::float64>,
01848    coutFunc<ito::complex64>,
01849    coutFunc<ito::complex128>,
01850    coutFunc<ito::Rgba32>
01851 };
01852 
01853 static inline std::ostream& operator << (std::ostream& out, const DataObject& dObj)
01854 {
01855    return fListCout[dObj.getType()](out, dObj);
01856 }
01857 
01859 
01866 static ito::tDataType convertCmplxTypeToRealType(ito::tDataType cmplxType)
01867 {
01868     switch(cmplxType)
01869     {
01870         case ito::tInt8:
01871         case ito::tUInt8:
01872         case ito::tInt16:
01873         case ito::tUInt16:
01874         case ito::tInt32:
01875         case ito::tUInt32:
01876         case ito::tFloat32:
01877         case ito::tFloat64:
01878         case ito::tRGBA32:
01879             return cmplxType;
01880         case ito::tComplex64:
01881             return ito::tFloat32;
01882         case ito::tComplex128:
01883             return ito::tFloat64;
01884     }
01885 
01886     cv::error(cv::Exception(CV_StsAssert, "Input data type unknown", "", __FILE__, __LINE__));
01887     return ito::tInt8;
01888 }
01889 
01891 
01898 static ito::tDataType guessDataTypeFromCVMat(const cv::Mat* mat, ito::RetVal &retval)
01899 {
01900     if (mat)
01901     {
01902         switch(mat->type())
01903         {
01904         case cv::DataType<ito::int8>::type:
01905             return ito::tInt8;
01906         case cv::DataType<ito::uint8>::type:
01907             return ito::tUInt8;
01908         case cv::DataType<ito::int16>::type:
01909             return ito::tInt16;
01910         case cv::DataType<ito::uint16>::type:
01911             return ito::tUInt16;
01912         case cv::DataType<ito::int32>::type:
01913             return ito::tInt32;
01914         case cv::DataType<ito::uint32>::type:
01915             return ito::tUInt32;
01916         case cv::DataType<ito::float32>::type:
01917             return ito::tFloat32;
01918         case cv::DataType<ito::float64>::type:
01919             return ito::tFloat64;
01920         case cv::DataType<ito::Rgba32>::type:
01921             return ito::tRGBA32;
01922         case cv::DataType<ito::complex64>::type:
01923             return ito::tComplex64;
01924         case cv::DataType<ito::complex128>::type:
01925             return ito::tComplex128;
01926         }
01927 
01928         retval += ito::RetVal(ito::retError, 0, "type of cv::Mat is incompatible to ito::DataObject");
01929     }
01930     else
01931     {
01932         retval += ito::RetVal(ito::retError, 0, "given cv::Mat is NULL.");
01933     }
01934     return ito::tInt8;
01935 }
01936 
01937 
01938 
01939 
01941 
01950 template<typename _Tp> static inline ito::tDataType getDataType2()
01951 {
01952     cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__));
01953     return ito::tInt8;
01954 }
01955 
01956 template<> inline ito::tDataType getDataType2<uint8*>()      { return ito::tUInt8; }
01957 template<> inline ito::tDataType getDataType2<int8*>()       { return ito::tInt8; }
01958 template<> inline ito::tDataType getDataType2<uint16*>()     { return ito::tUInt16; }
01959 template<> inline ito::tDataType getDataType2<int16*>()      { return ito::tInt16; }
01960 template<> inline ito::tDataType getDataType2<uint32*>()     { return ito::tUInt32; }
01961 template<> inline ito::tDataType getDataType2<int32*>()      { return ito::tInt32; }
01962 template<> inline ito::tDataType getDataType2<float32*>()    { return ito::tFloat32; }
01963 template<> inline ito::tDataType getDataType2<float64*>()    { return ito::tFloat64; }
01964 template<> inline ito::tDataType getDataType2<complex64*>()  { return ito::tComplex64; }
01965 template<> inline ito::tDataType getDataType2<complex128*>() { return ito::tComplex128; }
01966 template<> inline ito::tDataType getDataType2<Rgba32*>() { return ito::tRGBA32; }
01967 
01969 
01979 template<typename _Tp> static inline bool isZeroValue(_Tp v, _Tp /*epsilon*/)
01980 {
01981     return v == 0;
01982 }
01983 template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/)
01984 {
01985     return v == Rgba32::zeros();
01986 }
01987 template<> inline bool isZeroValue(float32 v, float32 epsilon)
01988 {
01989     return v >= epsilon ? false : (v <= -epsilon ? false : true);
01990 }
01991 template<> inline bool isZeroValue(float64 v, float64 epsilon)
01992 {
01993     return v >= epsilon ? false : (v <= -epsilon ? false : true);
01994 }
01995 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon)
01996 {
01997     return isZeroValue<ito::float32>(v.real(),epsilon.real()) && isZeroValue<ito::float32>(v.imag(),epsilon.real());
01998 }
01999 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon)
02000 {
02001     return isZeroValue<ito::float64>(v.real(),epsilon.real()) && isZeroValue<ito::float64>(v.imag(),epsilon.real());
02002 }
02003 
02004 
02005 //----------------------------------------------------------------------------------------------------------------------------------
02006 // friend functions to access private members of DataObject
02007 //----------------------------------------------------------------------------------------------------------------------------------
02008 } //namespace ito
02009 
02010 #endif //__DATAOBJH
02011 
02012 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends