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/ICLGeom/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.GPL ** 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 <ICLMath/FixedVector.h> 00034 #include <ICLCore/CoreFunctions.h> 00035 #include <ICLGeom/DataSegmentBase.h> 00036 #include <ICLUtils/ClippedCast.h> 00037 00038 namespace icl{ 00039 namespace geom{ 00040 00041 00043 00145 template<class T,int N> 00146 struct DataSegment : public DataSegmentBase{ 00148 typedef math::FixedColVector<T,N> VectorType; 00149 00151 inline DataSegment(T *data=0, size_t stride=0, size_t numElements=0, icl32s organizedWidth=-1): 00152 DataSegmentBase(data,stride,numElements,organizedWidth,icl::core::getDepth<T>(),N){} 00153 00155 inline math::FixedColVector<T,N> &operator[](int idx) { 00156 return *reinterpret_cast<math::FixedColVector<T,N>*>(data +idx*stride); 00157 } 00158 00160 inline const math::FixedColVector<T,N> &operator[](int idx) const{ 00161 return const_cast<DataSegment<T,N> *>(this)->operator[](idx); 00162 } 00163 00165 inline math::FixedColVector<T,N> &operator()(int x, int y) { 00166 return operator[](x + organizedWidth * y ); 00167 } 00168 00170 inline const math::FixedColVector<T,N> &operator()(int x, int y) const{ 00171 return operator[](x + organizedWidth * y ); 00172 } 00173 00175 template<class OtherT> 00176 inline void deepCopy(DataSegment<OtherT,N> dst) const throw (utils::ICLException); 00177 00179 inline bool isPacked() const{ 00180 return stride == sizeof(T)*N; 00181 } 00182 00184 00186 template<class OtherT> 00187 inline bool equals(DataSegment<OtherT,N> dst, float tollerance = 1.0e-5) const { 00188 if(getDim() != dst.getDim()) return false; 00189 if(isOrganized() != dst.isOrganized()) return false; 00190 if(isOrganized() && getSize() != dst.getSize()) return false; 00191 const int dim = getDim(); 00192 for(int i=0;i<dim;++i){ 00193 for(int j=0;j<N;++j){ 00194 if(fabs(operator[](i)[j] - dst[i][j]) > tollerance) return false; 00195 } 00196 } 00197 return true; 00198 } 00199 00201 00208 template<class Fill> 00209 inline void fillScalar(Fill scalarValue){ 00210 const int dim = getDim(); 00211 for(int i=0;i<dim;++i){ 00212 for(int j=0;j<N;++j){ 00213 operator[](i)[j] = scalarValue; 00214 } 00215 } 00216 } 00217 00219 00221 template<class Fill> 00222 inline void fill(Fill vecValue){ 00223 const int dim = getDim(); 00224 for(int i=0;i<dim;++i){ 00225 operator[](i) = vecValue; 00226 } 00227 } 00228 }; 00229 00230 00232 template<class T, class OtherT, int N> 00233 struct DataSegmentDeepCopyUtil{ 00234 static void copy(const DataSegment<T,N> &src, DataSegment<OtherT,N> &dst){ 00235 const int dim = src.getDim(); 00236 const bool sp = src.isPacked(), dp = dst.isPacked(); 00237 if(sp && dp){ 00238 const T *s = (const T*)src.begin(); 00239 T *d = (T*)dst.begin(); 00240 std::transform(s,s+dim*N,d,icl::utils::clipped_cast<T,OtherT>); 00241 }else if(sp){ 00242 const math::FixedColVector<T,N> *srcpacked = &src[0]; 00243 for(int i=0;i<dim;++i){ 00244 dst[i] = srcpacked[i]; 00245 } 00246 }else if(dp){ 00247 math::FixedColVector<T,N> *dstpacked = &dst[0]; 00248 for(int i=0;i<dim;++i){ 00249 dstpacked[i] = src[i]; 00250 } 00251 }else{ 00252 for(int i=0;i<dim;++i){ 00253 dst[i] = src[i]; 00254 } 00255 } 00256 } 00257 }; 00258 00259 template<class T, int N> 00260 struct DataSegmentDeepCopyUtil<T,T,N>{ 00261 static void copy(const DataSegment<T,N> &src, DataSegment<T,N> &dst){ 00262 const int dim = src.getDim(); 00263 const bool sp = src.isPacked(), dp = dst.isPacked(); 00264 if(sp && dp){ 00265 memcpy(dst.getDataPointer(),src.getDataPointer(),dim*sizeof(T)*N); 00266 }else if(sp){ 00267 const math::FixedColVector<T,N> *srcpacked = &src[0]; 00268 for(int i=0;i<dim;++i){ 00269 dst[i] = srcpacked[i]; 00270 } 00271 }else if(dp){ 00272 math::FixedColVector<T,N> *dstpacked = &dst[0]; 00273 for(int i=0;i<dim;++i){ 00274 dstpacked[i] = src[i]; 00275 } 00276 }else{ 00277 for(int i=0;i<dim;++i){ 00278 dst[i] = src[i]; 00279 } 00280 } 00281 } 00282 }; 00283 00284 template<class T, int N> template<class OtherT> 00285 inline void DataSegment<T,N>::deepCopy(DataSegment<OtherT,N> dst) const throw (utils::ICLException){ 00286 ICLASSERT_THROW(getDim() == dst.getDim(), 00287 utils::ICLException("error in DataSegment::deepCopy " 00288 "(source and destination dim differ)")); 00289 DataSegmentDeepCopyUtil<T,OtherT,N>::copy(*this,dst); 00290 } 00291 00292 00295 00296 00300 template<class T> 00301 struct DataSegment<T,1> : public DataSegmentBase{ 00303 typedef T VectorType; 00304 00306 inline DataSegment(T *data=0, size_t stride=0, size_t numElements=0, icl32s organizedWidth=-1): 00307 DataSegmentBase(data,stride,numElements,organizedWidth,icl::core::getDepth<T>(),1){} 00308 00310 inline T &operator[](int idx) { 00311 return *reinterpret_cast<T*>(data +idx*stride); 00312 } 00313 00315 inline const T &operator[](int idx) const{ 00316 return const_cast<DataSegment<T,1>*>(this)->operator[](idx); 00317 } 00318 00320 inline T &operator()(int x, int y) { 00321 return operator[](x + organizedWidth * y ); 00322 } 00323 00325 inline const T &operator()(int x, int y) const{ 00326 return operator[](x + organizedWidth * y ); 00327 } 00328 00330 template<class OtherT> 00331 inline void deepCopy(DataSegment<OtherT,1> dst) const throw (utils::ICLException){ 00332 ICLASSERT_THROW(getDim() == dst.getDim(), 00333 utils::ICLException("error in DataSegment::deepCopy " 00334 "(source and destination dim differ)")); 00335 const int dim = getDim(); 00336 for(int i=0;i<dim;++i){ 00337 dst[i] = operator[](i); 00338 } 00339 } 00340 template<class OtherT> 00341 inline bool equals(DataSegment<OtherT,1> dst, float tollerance = 1.0e-5) const { 00342 if(getDim() != dst.getDim()) return false; 00343 if(isOrganized() != dst.isOrganized()) return false; 00344 if(isOrganized() && getSize() != dst.getSize()) return false; 00345 const int dim = getDim(); 00346 for(int i=0;i<dim;++i){ 00347 if(fabs(operator[](i) - dst[i]) > tollerance) return false; 00348 } 00349 return true; 00350 } 00351 00353 00354 template<class Fill> 00355 inline void fillScalar(Fill scalarValue){ 00356 const int dim = getDim(); 00357 for(int i=0;i<dim;++i){ 00358 operator[](i) = scalarValue; 00359 } 00360 } 00361 00363 template<class Fill> 00364 inline void fill(Fill vecValue){ 00365 const int dim = getDim(); 00366 for(int i=0;i<dim;++i){ 00367 operator[](i) = vecValue; 00368 } 00369 } 00370 }; 00371 00373 template<class T, int N> 00374 const DataSegment<T,N> &DataSegmentBase::as() const{ 00375 if(dataDepth != icl::core::getDepth<T>()) throw utils::ICLException("invalid cast of data segment (core::depth is wrong)"); 00376 if(elemDim != N) throw utils::ICLException("invalid cast of data segment (dimension is wrong)"); 00377 return (DataSegment<T,N> &)(*this); 00378 } 00379 00384 } // namespace geom 00385 } 00386