Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLGeom/src/ICLCore/DataSegment.h ** 00010 ** Module : ICLGeom ** 00011 ** Authors: Christof Elbrechter, Patrick Nobou ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 #pragma once 00032 00033 #include <ICLUtils/CompatMacros.h> 00034 #include <ICLMath/FixedVector.h> 00035 #include <ICLCore/CoreFunctions.h> 00036 #include <ICLCore/DataSegmentBase.h> 00037 #include <ICLUtils/ClippedCast.h> 00038 00039 namespace icl{ 00040 namespace core{ 00041 00042 00044 00146 template<class T,int N> 00147 struct DataSegment : public DataSegmentBase{ 00149 typedef math::FixedColVector<T,N> VectorType; 00150 00152 inline DataSegment(T *data=0, size_t stride=0, size_t numElements=0, icl32s organizedWidth=-1): 00153 DataSegmentBase(data,stride,numElements,organizedWidth,icl::core::getDepth<T>(),N){} 00154 00156 inline math::FixedColVector<T,N> &operator[](int idx) { 00157 return *reinterpret_cast<math::FixedColVector<T,N>*>(data +idx*stride); 00158 } 00159 00161 inline const math::FixedColVector<T,N> &operator[](int idx) const{ 00162 return const_cast<DataSegment<T,N> *>(this)->operator[](idx); 00163 } 00164 00166 inline math::FixedColVector<T,N> &operator()(int x, int y) { 00167 return operator[](x + organizedWidth * y ); 00168 } 00169 00171 inline const math::FixedColVector<T,N> &operator()(int x, int y) const{ 00172 return operator[](x + organizedWidth * y ); 00173 } 00174 00176 template<class OtherT> 00177 inline void deepCopy(DataSegment<OtherT,N> dst) const throw (utils::ICLException); 00178 00180 inline bool isPacked() const{ 00181 return stride == sizeof(T)*N; 00182 } 00183 00185 00187 template<class OtherT> 00188 inline bool equals(DataSegment<OtherT,N> dst, float tollerance = 1.0e-5) const { 00189 if(getDim() != dst.getDim()) return false; 00190 if(isOrganized() != dst.isOrganized()) return false; 00191 if(isOrganized() && getSize() != dst.getSize()) return false; 00192 const int dim = getDim(); 00193 for(int i=0;i<dim;++i){ 00194 for(int j=0;j<N;++j){ 00195 if(fabs((float)(operator[](i)[j] - dst[i][j])) > tollerance) return false; 00196 } 00197 } 00198 return true; 00199 } 00200 00202 00209 template<class Fill> 00210 inline void fillScalar(Fill scalarValue){ 00211 const int dim = getDim(); 00212 for(int i=0;i<dim;++i){ 00213 for(int j=0;j<N;++j){ 00214 operator[](i)[j] = scalarValue; 00215 } 00216 } 00217 } 00218 00220 00222 template<class Fill> 00223 inline void fill(Fill vecValue){ 00224 const int dim = getDim(); 00225 for(int i=0;i<dim;++i){ 00226 operator[](i) = vecValue; 00227 } 00228 } 00229 }; 00230 00231 00233 template<class T, class OtherT, int N> 00234 struct DataSegmentDeepCopyUtil{ 00235 static void copy(const DataSegment<T,N> &src, DataSegment<OtherT,N> &dst){ 00236 const int dim = src.getDim(); 00237 const bool sp = src.isPacked(), dp = dst.isPacked(); 00238 if(sp && dp){ 00239 const T *s = (const T*)src.begin(); 00240 T *d = (T*)dst.begin(); 00241 std::transform(s,s+dim*N,d,icl::utils::clipped_cast<T,OtherT>); 00242 }else if(sp){ 00243 const math::FixedColVector<T,N> *srcpacked = &src[0]; 00244 for(int i=0;i<dim;++i){ 00245 dst[i] = srcpacked[i]; 00246 } 00247 }else if(dp){ 00248 math::FixedColVector<OtherT,N> *dstpacked = &dst[0]; 00249 for(int i=0;i<dim;++i){ 00250 dstpacked[i] = src[i]; 00251 } 00252 }else{ 00253 for(int i=0;i<dim;++i){ 00254 dst[i] = src[i]; 00255 } 00256 } 00257 } 00258 }; 00259 00260 template<class T, int N> 00261 struct DataSegmentDeepCopyUtil<T,T,N>{ 00262 static void copy(const DataSegment<T,N> &src, DataSegment<T,N> &dst){ 00263 const int dim = src.getDim(); 00264 const bool sp = src.isPacked(), dp = dst.isPacked(); 00265 if(sp && dp){ 00266 memcpy(dst.getDataPointer(),src.getDataPointer(),dim*sizeof(T)*N); 00267 }else if(sp){ 00268 const math::FixedColVector<T,N> *srcpacked = &src[0]; 00269 for(int i=0;i<dim;++i){ 00270 dst[i] = srcpacked[i]; 00271 } 00272 }else if(dp){ 00273 math::FixedColVector<T,N> *dstpacked = &dst[0]; 00274 for(int i=0;i<dim;++i){ 00275 dstpacked[i] = src[i]; 00276 } 00277 }else{ 00278 for(int i=0;i<dim;++i){ 00279 dst[i] = src[i]; 00280 } 00281 } 00282 } 00283 }; 00284 00285 template<class T, int N> template<class OtherT> 00286 inline void DataSegment<T,N>::deepCopy(DataSegment<OtherT,N> dst) const throw (utils::ICLException){ 00287 ICLASSERT_THROW(getDim() == dst.getDim(), 00288 utils::ICLException("error in DataSegment::deepCopy " 00289 "(source and destination dim differ)")); 00290 DataSegmentDeepCopyUtil<T,OtherT,N>::copy(*this,dst); 00291 } 00292 00293 00296 00297 00301 template<class T> 00302 struct DataSegment<T,1> : public DataSegmentBase{ 00304 typedef T VectorType; 00305 00307 inline DataSegment(T *data=0, size_t stride=0, size_t numElements=0, icl32s organizedWidth=-1): 00308 DataSegmentBase(data,stride,numElements,organizedWidth,icl::core::getDepth<T>(),1){} 00309 00311 inline T &operator[](int idx) { 00312 return *reinterpret_cast<T*>(data +idx*stride); 00313 } 00314 00316 inline const T &operator[](int idx) const{ 00317 return const_cast<DataSegment<T,1>*>(this)->operator[](idx); 00318 } 00319 00321 inline T &operator()(int x, int y) { 00322 return operator[](x + organizedWidth * y ); 00323 } 00324 00326 inline const T &operator()(int x, int y) const{ 00327 return operator[](x + organizedWidth * y ); 00328 } 00329 00331 template<class OtherT> 00332 inline void deepCopy(DataSegment<OtherT,1> dst) const throw (utils::ICLException){ 00333 ICLASSERT_THROW(getDim() == dst.getDim(), 00334 utils::ICLException("error in DataSegment::deepCopy " 00335 "(source and destination dim differ)")); 00336 const int dim = getDim(); 00337 for(int i=0;i<dim;++i){ 00338 dst[i] = operator[](i); 00339 } 00340 } 00341 template<class OtherT> 00342 inline bool equals(DataSegment<OtherT,1> dst, float tollerance = 1.0e-5) const { 00343 if(getDim() != dst.getDim()) return false; 00344 if(isOrganized() != dst.isOrganized()) return false; 00345 if(isOrganized() && getSize() != dst.getSize()) return false; 00346 const int dim = getDim(); 00347 for(int i=0;i<dim;++i){ 00348 if(fabs((float)(operator[](i) - dst[i])) > tollerance) return false; 00349 } 00350 return true; 00351 } 00352 00354 00355 template<class Fill> 00356 inline void fillScalar(Fill scalarValue){ 00357 const int dim = getDim(); 00358 for(int i=0;i<dim;++i){ 00359 operator[](i) = scalarValue; 00360 } 00361 } 00362 00364 template<class Fill> 00365 inline void fill(Fill vecValue){ 00366 const int dim = getDim(); 00367 for(int i=0;i<dim;++i){ 00368 operator[](i) = vecValue; 00369 } 00370 } 00371 }; 00372 00374 template<class T, int N> 00375 const DataSegment<T,N> &DataSegmentBase::as() const{ 00376 if(dataDepth != icl::core::getDepth<T>()) throw utils::ICLException("invalid cast of data segment (core::depth is wrong)"); 00377 if(elemDim != N) throw utils::ICLException("invalid cast of data segment (dimension is wrong)"); 00378 return (DataSegment<T,N> &)(*this); 00379 } 00380 00385 } // namespace core 00386 } 00387