Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Img.h
Go to the documentation of this file.
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   : ICLCore/src/ICLCore/Img.h                              **
00010 ** Module : ICLCore                                                **
00011 ** Authors: Christof Elbrechter, Michael Goetting, Robert          **
00012 **          Haschke, Andre Justus, Sergius Gaulik                  **
00013 **                                                                 **
00014 **                                                                 **
00015 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00016 ** This file may be used under the terms of the GNU Lesser General **
00017 ** Public License version 3.0 as published by the                  **
00018 **                                                                 **
00019 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
00020 ** included in the packaging of this file.  Please review the      **
00021 ** following information to ensure the license requirements will   **
00022 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00023 **                                                                 **
00024 ** The development of this software was supported by the           **
00025 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00026 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00027 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00028 ** Excellence Initiative.                                          **
00029 **                                                                 **
00030 ********************************************************************/
00031 
00032 #pragma once
00033 
00034 #include <ICLUtils/SmartPtr.h>
00035 #include <ICLUtils/Exception.h>
00036 #include <ICLCore/ImgBase.h>
00037 #include <ICLCore/ImgIterator.h>
00038 #include <ICLCore/Channel.h>
00039 #include <ICLCore/PixelRef.h>
00040 #include <ICLMath/DynMatrix.h>
00041 #include <cmath>
00042 #include <algorithm>
00043 
00044 
00045 namespace icl {
00046   namespace core{
00048     template<class Type>
00049     class ICLCore_API Img : public ImgBase
00050     {
00051          
00052       /* this is declare as fried, because it accesses the private append function */
00053       template<class ImgType> friend 
00054       const ImgType* combineImages (const std::vector<const ImgType*>& vec, ImgBase** ppoDst);
00055      
00057 
00060       Img<Type>& shallowCopy(const Img<Type>& tSource);
00061       
00063 
00066       void append(const Img<Type> *src, int iChannel=-1);
00067   
00069 
00072       void append(const Img<Type> *src, const std::vector<int>& vChannels);
00073   
00074       protected:
00075          
00077       /* {{{ open */
00078   
00080       std::vector<utils::SmartArray<Type> > m_vecChannels;
00082   
00083       /* }}} */
00084   
00086       /* {{{ open */
00087   
00089 
00092       utils::SmartArray<Type> createChannel(Type *ptDataToCopy=0) const;
00093   
00095 
00121       int getStartIndex(int iIndex) const { return iIndex < 0 ? 0 : iIndex; }
00122   
00124 
00129       int getEndIndex(int iIndex) const { return iIndex < 0 ? getChannels() : iIndex+1; }
00130   
00132   
00133       /* }}} */
00134             
00136       /* {{{ open */
00137   
00139 
00148       void normalize(int iChannel, 
00149                      const utils::Range<Type> &srcRange, 
00150                      const utils::Range<Type> &dstRange);
00151   
00153 
00158       void mirror(axis eAxis, int iChannel,
00159                   const utils::Point& oOffset,
00160                   const utils::Size& oSize);
00162       /* }}} */
00163       
00164       public:
00165       
00167       static const Img<Type> null;
00168       
00169       /* {{{ open */
00171 
00174       Img(const ImgParams &params = ImgParams::null);
00175     
00177 
00181       Img(const utils::Size &size, int channels);
00182    
00184 
00187       Img(const utils::Size &s, format fmt);
00188    
00190 
00197       Img(const utils::Size &s, int channels, format fmt);
00198     
00200 
00211       Img(const utils::Size &size, format format, const std::vector<Type*>& vptData, 
00212           bool passOwnerShip=false);
00213     
00215 
00226       Img(const utils::Size &size, int channels, 
00227           const std::vector<Type*>& vptData, bool passOwnerShip=false);
00228   
00230 
00243       Img(const utils::Size &size, int channels, format fmt, 
00244           const std::vector<Type*>& vptData, bool passOwnerShip=false);
00245   
00247 
00262       Img(const Img<Type>& tSrc);
00263       
00264   
00266 
00278       Img(const math::DynMatrix<Type> &c1, 
00279           const math::DynMatrix<Type> &c2=math::DynMatrix<Type>(), 
00280           const math::DynMatrix<Type> &c3=math::DynMatrix<Type>(), 
00281           const math::DynMatrix<Type> &c4=math::DynMatrix<Type>(), 
00282           const math::DynMatrix<Type> &c5=math::DynMatrix<Type>()) throw (math::InvalidMatrixDimensionException);
00283   
00284       
00286       ~Img();
00287   
00289       bool isNull() const{
00290         return getSize()==utils::Size::null && getChannels() == 0;
00291       }
00292       
00293   
00294       /* }}} */
00295     
00297       /* {{{ open */
00298       
00300       operator Img<Type>&(){
00301         return *this;
00302       }
00303   
00305       operator const Img<Type>&() const {
00306         return *this;
00307       }
00308   
00310 
00324       Img<Type>& operator=(const Img<Type>& tSource) {
00325         // call private const-version
00326         return this->shallowCopy (static_cast<const Img<Type>&>(tSource));
00327       }
00328       /*
00329           #ifdef WIN32  
00330           Img<Type>& operator=(const Img<Type>& tSource) {
00331           // call private const-version
00332           return this->shallowCopy (static_cast<const Img<Type>&>(tSource));
00333           }
00334           #endif
00335           
00336           #ifdef GCC_VER_423
00337           Img<Type>& operator=(const Img<Type>& tSource) {
00338           // call private const-version
00339           return this->shallowCopy (static_cast<const Img<Type>&>(tSource));
00340           }
00341           #endif
00342       */
00343   
00345 
00372       Type& operator()(int iX, int iY, int iChannel) {
00373         return const_cast<Type&>(static_cast<const Img<Type>*>(this)->operator()(iX,iY,iChannel)); 
00374       }
00375       
00377       const Type& operator()(int iX, int iY, int iChannel) const { 
00378         return getData(iChannel)[iX+getWidth()*iY]; 
00379       }
00380       
00382 
00387       inline PixelRef<Type> operator()(int x, int y){
00388         return PixelRef<Type>(x,y,getWidth(),m_vecChannels);
00389       }
00390   
00392       inline const PixelRef<Type> operator()(int x, int y) const{
00393         return const_cast<Img<Type>*>(this)->operator()(x,y);
00394       }
00395       
00397 
00399       inline Channel<Type> operator[](int channel) {
00400         return Channel<Type>(begin(channel),getSize(),getROI());
00401       }
00402   
00404 
00406       inline const Channel<Type> operator[](int channel) const {
00407         return Channel<Type>(const_cast<Type*>(begin(channel)),getSize(),getROI());
00408       }
00409   
00410   
00412       float subPixelNN(float fX, float fY, int iChannel) const {
00413         return (*this)((int)fX, (int)fY, iChannel);
00414       }
00415 
00417       float subPixelLIN(float fX, float fY, int iChannel) const;
00418     
00420       float subPixelRA(float fX, float fY, float w, float h, int iChannel) const;
00421       float subPixelRA(const unsigned int xB, const unsigned int xE,
00422                        const unsigned int yB, const unsigned int yE,
00423                        const float xBMul, const float xEMul, const float BMul, const float yEMul,
00424                        const Type *d, const unsigned int w) const;
00425   
00427       Type operator()(float fX, float fY, int iChannel, scalemode eMode) const;
00428     
00430   
00431       /* }}} */
00432   
00434       /* {{{ open  */
00435   
00436       /*inline <Type> operator[](int channel) throw (InvalidMatrixDimensionException){
00437         return DynMatrix<Type>(getWidth(),getHeight(),begin(channel),false);
00438       }*/
00439       
00441       /* This function cannot be called on (0,x) or (x,0)-sized images */
00442       inline math::DynMatrix<Type> extractDynMatrix(int channel) 
00443         throw (math::InvalidMatrixDimensionException){ 
00444         return math::DynMatrix<Type>(getWidth(),getHeight(),begin(channel),false);
00445       }
00447       /* This function cannot be called on (0,x) or (x,0)-sized images */
00448       inline const math::DynMatrix<Type> extractDynMatrix(int channel) const 
00449         throw (math::InvalidMatrixDimensionException){ 
00450         return math::DynMatrix<Type>(getWidth(),getHeight(),const_cast<Type*>(begin(channel)),false);
00451       }
00452       
00454       inline void extractChannels(Channel<Type> *dst){
00455         ICLASSERT_RETURN(dst);
00456         for(int i=0;i<getChannels();++i){
00457           dst[i] = (*this)[i];
00458         }
00459       }
00460   
00462 
00463       inline void extractChannels(Channel<Type> *dst) const{
00464         (void)dst;
00465         ERROR_LOG("extracting channels of a const Img into an un-const Channel\n"
00466                   "is forbidden because it violates the const concept");
00467       }
00468   
00470 
00471       inline void extractChannels(const Channel<Type> *dst) const{
00472         return const_cast<Img<Type>*>(this)->extractChannels(const_cast<Channel<Type>*>(dst));
00473       }
00474   
00476       inline void extractPointers(Type **dst){
00477         for(int i=0;i<getChannels();++i){
00478           dst[i] = begin(i);
00479         }
00480       }
00481   
00483 
00484       inline void extractPointers(Type **dst) const{
00485         (void)dst;
00486         ERROR_LOG("extracting channel data of a const Img into an un-const pointer\n"
00487                   "is forbidden because it violates the const concept");
00488       }
00489   
00491       inline void extractPointers(const Type **dst) const{
00492         for(int i=0;i<getChannels();++i){
00493           dst[i] = begin(i);
00494         }
00495       }
00496   
00497   
00498   
00500   
00501       /* }}} */
00502   
00503     
00505       /* {{{ open  */
00506                     
00507       virtual Img<Type> *shallowCopy(const utils::Rect &roi, 
00508                                      const std::vector<int> &channelIndices,
00509                                      format fmt,
00510                                      utils::Time time = utils::Time::null,
00511                                      ImgBase **ppoDst = NULL);
00512   
00525         const Img<Type> *shallowCopy(const utils::Rect &roi, 
00526                                      const std::vector<int> &channelIndices,
00527                                      format fmt, 
00528                                      utils::Time time=utils::Time::null) const{
00529           // casting constness away is safe, because we effectively return a const Img<Type>*
00530           return const_cast<Img<Type>*>(this)->shallowCopy(roi,channelIndices,fmt,time,0);
00531         }
00532         
00533   
00535 
00540         Img<Type> *reinterpretChannels(format newFmt, Img<Type> *poDst = NULL){
00541            ImgBase *poDstBase = poDst;
00542            return shallowCopy(getROI(),std::vector<int>(),newFmt,getTime(),&poDstBase);
00543         }
00544         
00545         
00547 
00551         const Img<Type> *reinterpretChannels(format newFmt){
00552           return shallowCopy(getROI(),std::vector<int>(),newFmt,getTime());
00553         }
00555 
00566         Img<Type>* shallowCopy(const utils::Rect &roi,Img<Type>* poDst = NULL){
00567           ImgBase *poDstBase = poDst;
00568           return shallowCopy(roi,std::vector<int>(),getFormat(),getTime(),&poDstBase);
00569         }
00570   
00572 
00581         const Img<Type>* shallowCopy(const utils::Rect& roi) const {
00582            // casting constness away is safe, because we effectively return a const Img<Type>*
00583            return const_cast<Img<Type>*>(this)->shallowCopy(roi,0);
00584         }
00585        
00586   
00588 
00597         Img<Type>* selectChannels (const std::vector<int>& channelIndices, Img<Type>* poDst=0){
00598           ImgBase *poDstBase = poDst;
00599           return shallowCopy(getROI(),channelIndices,formatMatrix,getTime(),&poDstBase);
00600         }
00601   
00603 
00610         Img<Type> *selectChannel(int channelIndex, Img<Type> *poDst=0){
00611           ICLASSERT_RETURN_VAL(validChannel(channelIndex), 0);
00612           std::vector<int> v(1); v[0]= channelIndex; 
00613           return selectChannels(v,poDst);
00614         }
00616 
00619         const Img<Type>* selectChannels (const std::vector<int>& channelIndices) const {
00620            // casting constness away is safe, because we effectively return a const Img<Type>*
00621            return const_cast<Img<Type>*>(this)->selectChannels(channelIndices, 0);
00622         }
00623         
00625 
00631         const Img<Type> *selectChannel(int channelIndex) const{
00632           ICLASSERT_RETURN_VAL(validChannel(channelIndex), 0);
00633           std::vector<int> v(1); v[0]= channelIndex; return selectChannels(v);
00634         }
00635   
00636         //------------------------------------------------------------------------------   
00637         //------------------------------------------------------------------------------    
00638         //------------------------------------------------------------------------------   
00639   
00640   
00641   
00642   
00643   
00645 
00646       virtual Img<Type>* deepCopy(ImgBase** ppoDst=0) const;
00647   
00649 
00656       Img<Type> *deepCopy(Img<Type> *poDst) const;
00657   
00659 
00660       virtual Img<Type> *deepCopyROI(ImgBase **ppoDst=0) const;
00661   
00662       
00664 
00674       Img<Type> *deepCopyROI(Img<Type> *poDst) const;
00675   
00677       /* }}} */
00678     
00680       /* {{{ open */
00681      
00683 
00684       virtual Img<Type> *scaledCopy(const utils::Size &newSize, scalemode eScaleMode=interpolateNN) const;
00685       
00687 
00688       virtual Img<Type> *scaledCopy(ImgBase **ppoDst=0, scalemode eScaleMode=interpolateNN) const;
00689   
00690      
00692 
00698       Img<Type> *scaledCopy(Img<Type> *poDst, scalemode eScaleMode=interpolateNN) const;
00699       
00701 
00702       virtual Img<Type> *scaledCopyROI(const utils::Size &newSize, scalemode eScaleMode=interpolateNN) const;
00703       
00705 
00706       virtual Img<Type> *scaledCopyROI(ImgBase **ppoDst=0, scalemode eScaleMode=interpolateNN) const;
00707       
00709 
00715       Img<Type> *scaledCopyROI(Img<Type> *poDst, scalemode eScaleMode=interpolateNN) const;    
00716   
00718       /* }}} */
00719   
00721       /* {{{ open */
00722   
00724 
00725       virtual void detach(int iIndex = -1);
00726       
00728 
00735       inline Img<Type> detached() const {
00736         Img<Type> detachedCopy = *this;
00737         detachedCopy.detach();
00738         return detachedCopy;
00739       }
00740     
00742 
00743       virtual void removeChannel(int iChannel);
00744     
00746 
00756       void append(Img<Type> *src, int iChannel=-1) {
00757         // call private const-version
00758         this->append (static_cast<const Img<Type>*>(src), iChannel);
00759       }
00760     
00762 
00764       void append(Img<Type> *src, const std::vector<int>& vChannels) {
00765         // call private const-version
00766         this->append (static_cast<const Img<Type>*>(src), vChannels);
00767       }  
00768   
00770 
00772       Img<Type> extractChannelImg(int index);
00773   
00775 
00777       const Img<Type> extractChannelImg(int index) const;
00778   
00780 
00782       Img<Type> extractChannelImg(const std::vector<int> &indices);
00783   
00785 
00787       const Img<Type> extractChannelImg(const std::vector<int> &indices) const;
00788   
00789       
00791 
00792       virtual void swapChannels(int iIndexA, int iIndexB);
00793     
00795 
00800       void replaceChannel(int iThisIndex, Img<Type> *poOtherImg, int iOtherIndex);
00801   
00803 
00804       virtual void setChannels(int iNewNumChannels);
00805   
00807 
00808       virtual void setSize(const utils::Size &s);
00809     
00811   
00812       /* }}} */
00813     
00815       /* {{{ open */
00816   
00818 
00822       Type getMax(int iChannel, utils::Point *coords=0) const;
00823     
00825 
00829       Type getMin(int iChannel, utils::Point *coords=0) const;
00830     
00831   
00833       Type getMin() const;
00834   
00836       Type getMax() const;
00837   
00839 
00845       const utils::Range<Type> getMinMax(int iChannel, 
00846                                          utils::Point *minCoords=0, 
00847                                          utils::Point *maxCoords=0) const;
00848   
00850       const utils::Range<Type> getMinMax() const;
00851   
00853 
00854       virtual int getLineStep() const{
00855         return getSize().width*sizeof(Type);
00856       }
00857   
00859 
00864       Type* getData(int iChannel) { 
00865         return const_cast<Type*>(static_cast<const Img<Type>*>(this)->getData(iChannel));
00866       }
00867       
00869 
00870       const Type* getData(int iChannel) const {
00871         FUNCTION_LOG("");
00872         ICLASSERT_RETURN_VAL(validChannel(iChannel), 0);
00873         return m_vecChannels[iChannel].get();
00874       }
00875     
00877 
00896       Type* getROIData(int iChannel) {
00897         return const_cast<Type*>(static_cast<const Img<Type>*>(this)->getROIData(iChannel));
00898       }
00899   
00901 
00902       const Type* getROIData(int iChannel) const {
00903         FUNCTION_LOG("");
00904         ICLASSERT_RETURN_VAL(validChannel(iChannel),0);
00905         return getData(iChannel) + m_oParams.getPixelOffset();
00906       }
00907   
00909 
00918       Type* getROIData(int iChannel, const utils::Point &p) {
00919         return const_cast<Type*>(static_cast<const Img<Type>*>(this)->getROIData(iChannel, p));
00920       } 
00922 
00923       const Type* getROIData(int iChannel, const utils::Point &p) const {
00924         FUNCTION_LOG("");
00925         ICLASSERT_RETURN_VAL(validChannel(iChannel),0);
00926         return getData(iChannel) + p.x + (p.y * getWidth());
00927       }
00928   
00930 
00931       virtual void* getDataPtr(int iChannel){
00932         return getData(iChannel);
00933       }
00934         
00936 
00937       virtual const void* getDataPtr(int iChannel) const{
00938         return getData(iChannel); 
00939       }
00940     
00942   
00943       /* }}} */
00944     
00946       /* {{{ open */
00947   
00948       
00950 
00976       template<typename UnaryFunction>
00977       inline Img<Type> &forEach_C(UnaryFunction f, int channel){
00978         ICLASSERT_RETURN_VAL(validChannel(channel),*this);
00979         if(hasFullROI()){
00980           std::for_each<Type*,UnaryFunction>(getData(channel),getData(channel)+getDim(),f);
00981         }else{
00982           const_roi_iterator end = endROI(channel);
00983           for(ImgIterator<Type> it = beginROI(channel); it != end; it.incRow()){
00984             std::for_each<Type*,UnaryFunction>(&(*it),&(*it)+it.getSubRectWidth(),f);
00985           }        
00986         }
00987         return *this;
00988       }
00989   
00991 
01010       template<typename UnaryFunction>
01011       inline Img<Type> &forEach(UnaryFunction f){
01012         for(int c=0;c<getChannels();++c){
01013           forEach_C(f,c);
01014         }
01015         return *this;
01016       }
01017       
01019 
01042       template<typename UnaryFunction, class dstType>
01043       inline Img<dstType> &transform_C(UnaryFunction f, int srcChannel, int dstChannel, Img<dstType> &dst) const{
01044         ICLASSERT_RETURN_VAL(getROISize() == dst.getROISize(),dst);
01045         ICLASSERT_RETURN_VAL(validChannel(srcChannel),dst);
01046         ICLASSERT_RETURN_VAL(dst.validChannel(dstChannel),dst);
01047   
01048         if(hasFullROI() && dst.hasFullROI()){
01049           std::transform(getData(srcChannel),getData(srcChannel)+getDim(),dst.getData(dstChannel),f);
01050         }else{
01051           ImgIterator<dstType> itDst = dst.beginROI(dstChannel);
01052           const_roi_iterator end = endROI(srcChannel);
01053           for(const_roi_iterator it = beginROI(srcChannel); it != end; it.incRow(), itDst.incRow()){
01054             std::transform(&(*it),&(*it)+it.getSubRectWidth(),&(*itDst),f);
01055           }        
01056         }
01057         return dst;
01058       }
01059     
01061 
01083       template<typename UnaryFunction,class dstType>
01084       inline Img<dstType> &transform(UnaryFunction f, Img<dstType> &dst) const{
01085         ICLASSERT_RETURN_VAL(getChannels() == dst.getChannels(),dst);
01086         for(int c=0;c<getChannels();++c){
01087           transform_C(f,c,c,dst);
01088         }
01089         return dst;
01090       }
01091   
01092   
01094 
01134       template<typename BinaryFunction, class dstType, class otherSrcType>
01135       inline Img<dstType> &combine_C(BinaryFunction f, 
01136                                      int thisChannel, 
01137                                      int otherSrcChannel, 
01138                                      int dstChannel, 
01139                                      const Img<otherSrcType> &otherSrc, 
01140                                      Img<dstType> &dst) const{
01141         ICLASSERT_RETURN_VAL(getROISize() == dst.getROISize()&& getROISize() == otherSrc.getROISize(),dst);
01142         ICLASSERT_RETURN_VAL(validChannel(thisChannel),dst);
01143         ICLASSERT_RETURN_VAL(otherSrc.validChannel(otherSrcChannel),dst);
01144         ICLASSERT_RETURN_VAL(dst.validChannel(dstChannel),dst);
01145   
01146         if(hasFullROI() && dst.hasFullROI() && otherSrc.hasFullROI()){
01147           std::transform(getData(thisChannel),getData(thisChannel)+getDim(),otherSrc.getData(otherSrcChannel),dst.getData(dstChannel),f);
01148         }else{
01149           ImgIterator<dstType> itDst = dst.beginROI(dstChannel);
01150           const ImgIterator<otherSrcType> itOtherSrc = otherSrc.beginROI(otherSrcChannel);
01151           const_roi_iterator end = endROI(thisChannel);
01152           for(const_roi_iterator it = beginROI(thisChannel); it!=end; it.incRow(), itDst.incRow(),itOtherSrc.incRow()){
01153             std::transform(&(*it),&(*it)+it.getROIWidth(),&(*itOtherSrc),&(*itDst),f);
01154           }        
01155         }
01156         return dst;
01157       }
01158   
01159       
01161 
01189       template<typename BinaryFunction, class dstType, class otherSrcType>
01190       inline Img<dstType> &combine(BinaryFunction f, const Img<otherSrcType> &otherSrc, Img<dstType> &dst) const{
01191         ICLASSERT_RETURN_VAL(getChannels() == otherSrc.getChannels(),dst);
01192         ICLASSERT_RETURN_VAL(getChannels() == dst.getChannels(),dst);
01193         for(int c=0;c<getChannels();++c){
01194           combine_C(f,c,c,c,otherSrc,dst);
01195         }
01196         return dst;
01197       }
01198       
01199   
01200   
01201       private:
01203       template<typename Tsrc, typename Tdst, int Nsrc, int Ndst, typename ReduceFunc>
01204       static inline void reduce_arrays(const Tsrc *src[Nsrc], Tdst *dst[Ndst], unsigned int dim, ReduceFunc reduce){
01205         for(int i=dim-1;i>=0;--i){
01206           Tsrc tsrc[Nsrc];      
01207           Tdst tdst[Ndst];
01208           for(int j=0;j<Nsrc;tsrc[j]=src[j][i],++j) {}
01209           reduce(tsrc,tdst);
01210           for(int j=0;j<Ndst;dst[j][i]=tdst[j],++j) {}
01211           
01212         }
01213       }
01214       
01215       public:
01216       
01217   
01219 
01253       template<typename Tdst, int Nthis, int Ndst, typename ReduceFunc>
01254       void reduce_channels(Img<Tdst> &dst, ReduceFunc reduce) const {
01255         ICLASSERT_RETURN(this->getROISize() == dst.getROISize());
01256         ICLASSERT_RETURN((Nthis > 0) && (Ndst > 0));
01257         ICLASSERT_RETURN((this->getChannels()==Nthis) &&  (dst.getChannels()==Ndst));
01258         
01259         const Type *psrc[Nthis];
01260         Tdst *pdst[Ndst];  
01261         if(this->hasFullROI() && dst.hasFullROI()){
01262           for(int i=0;i<Nthis;psrc[i]=this->getData(i),++i) {}
01263           for(int i=0;i<Ndst;pdst[i]=dst.getData(i),++i) {}
01264           reduce_arrays<Type,Tdst,Nthis,Ndst,ReduceFunc>(psrc,pdst,this->getDim(),reduce);
01265         }else{
01266           const_roi_iterator itSrc[Nthis];
01267           ImgIterator<Tdst> itDst[Ndst];
01268           for(int i=0;i<Nthis;itSrc[i]=this->beginROI(i),++i) {}
01269           for(int i=0;i<Ndst;itDst[i]=dst.beginROI(i),++i) {}
01270           
01271           for(int l=this->getROI().height-1, w=this->getROI().width ;l>=0;--l){
01272             for(int i=0;i<Nthis;itSrc[i].incRow(),++i){
01273               psrc[i]=&(*(itSrc[i]));
01274             }
01275             for(int i=0;i<Ndst;itDst[i].incRow(),++i){
01276               pdst[i]=&(*(itDst[i]));
01277             }
01278             reduce_arrays<Type,Tdst,Nthis,Ndst,ReduceFunc>(psrc,pdst,w,reduce);
01279           }
01280         }
01281       }
01282       
01284 
01287       Img<Type> *lut(const Type *lut, Img<Type> *dst = 0,int bits=8) const;
01288       
01290 
01291       virtual void scale(const utils::Size &s, scalemode eScaleMode=interpolateNN);
01292   
01294 
01295       virtual void mirror(axis eAxis, bool bOnlyROI=false);
01296     
01298 
01302       void clear(int iChannel = -1, Type tValue = 0, bool bROIOnly=true);
01303     
01305 
01321       template<class T>
01322       inline void fill(const T &value){
01323         for(int i=0;i<getChannels();++i){
01324           std::fill(begin(i),end(i),value);
01325         }
01326       }
01327   
01329       template<class T>
01330       inline void fillChannel(int channel, const T &value){
01331         std::fill(begin(channel),end(channel),value);
01332       }
01333       
01334   
01336       template<class T>
01337       inline void fillROI(const T &value){
01338         for(int i=0;i<getChannels();++i){
01339           std::fill(beginROI(i),endROI(i),value);
01340         }
01341       }
01342   
01344       template<class T>
01345       inline void fillChannelROI(int channel, const T &value){
01346         std::fill(beginROI(channel),endROI(channel),value);
01347       }
01348   
01349   
01351 
01355       void normalizeAllChannels(const utils::Range<Type> &dstRange);
01356   
01358 
01362       void normalizeChannel(int iChannel, const utils::Range<Type> &srcRange, 
01363                             const utils::Range<Type> &dstRange);
01364   
01366 
01371       void normalizeChannel(int iChannel,const utils::Range<Type> &dstRange);
01372   
01374 
01377       void normalizeImg(const utils::Range<Type> &srcRange, 
01378                         const utils::Range<Type> &dstRange);
01379     
01381 
01385       void normalizeImg(const utils::Range<Type> &dstRange);
01386     
01388   
01389       /* }}} */
01390     
01392       /* {{{ open */
01393       
01395       typedef Type* iterator;
01396   
01398       typedef const Type* const_iterator;
01399   
01401       typedef ImgIterator<Type> roi_iterator;
01402   
01404       typedef const ImgIterator<Type> const_roi_iterator;
01405       // old    typedef constConstImgIterator<Type> const_iterator;
01406       
01407   
01408   
01410       inline iterator begin(int channel){
01411         return getData(channel);
01412       }
01413       
01415       inline const_iterator begin(int channel) const{
01416         return const_cast<Img<Type>*>(this)->begin(channel);
01417       }
01418   
01420       iterator end(int channel){
01421         return getData(channel)+getDim();
01422       }
01423   
01425       const_iterator end(int channel) const{
01426         return getData(channel)+getDim();
01427       }
01428   
01430       inline roi_iterator beginROI(int channel){
01431         ICLASSERT_RETURN_VAL(validChannel(channel), roi_iterator());
01432         return roi_iterator(getData(channel),getWidth(),getROI());
01433       } 
01434   
01436       inline const_roi_iterator beginROI(int channel) const{
01437         ICLASSERT_RETURN_VAL(validChannel(channel), roi_iterator());
01438         return const_cast<Img<Type>*>(this)->beginROI(channel);
01439       } 
01440       
01442 
01443       inline roi_iterator endROI(int channel) {
01444         ICLASSERT_RETURN_VAL(validChannel(channel), roi_iterator());
01445         return roi_iterator::create_end_roi_iterator(getData(channel),getWidth(),getROI());
01446       }
01447   
01449       inline const_roi_iterator endROI(int channel) const{
01450         ICLASSERT_RETURN_VAL(validChannel(channel), roi_iterator());
01451         return const_roi_iterator::create_end_roi_iterator(getData(channel),getWidth(),getROI());
01452       }
01453   
01454       
01456 
01467       utils::Point getLocation(const Type *p, int channel, bool relToROI=false) const;
01468       
01470 
01476       void printAsMatrix(const std::string &format="5.3", bool visROI=true) const;
01477   
01479 
01480       virtual bool isIndependent() const;
01482   
01483       /* }}} */
01484   
01486       /* {{{ open */
01487         
01489 
01493       virtual void fillBorder(bool setFullROI=true);
01494       
01496       virtual void fillBorder(icl64f val, bool setFullROI=true);
01497       
01499 
01502       virtual void fillBorder(const std::vector<icl64f> &vals, bool setFullROI=true);
01503       
01504       
01506 
01510       virtual void fillBorder(const ImgBase *src, bool setFullROI=true);
01511       
01513       /* }}} */
01514   
01515     
01516     };// class Img<Type>
01517   
01518     
01519     /* {{{ global functions */
01520   
01522 
01525     template<class T> struct ICLCore_API ImgBasePtrPtr {
01527       ImgBasePtrPtr(Img<T> &i);
01528       
01530       ImgBasePtrPtr(Img<T> *i);
01531   
01533 
01543       ~ImgBasePtrPtr();
01544       
01546       operator ImgBase** (){ return &r; }
01547   
01548       private:
01550       ImgBase *o,*r,*rbef;
01551     };
01552 
01554 
01584     template<class T>
01585     ImgBasePtrPtr<T> bpp(Img<T> *image) { return ImgBasePtrPtr<T>(image); }
01586   
01588 
01589     template<class T>
01590     ImgBasePtrPtr<T> bpp(Img<T> &image) { return ImgBasePtrPtr<T>(image); }
01591     
01592   
01594 
01638     template<class T>
01639     static inline T p2o(T *ptr){
01640       return *utils::SmartPtr<T>(ptr);
01641     }
01642   
01644     template<class ImgType>
01645     const ImgType* combineImages(const std::vector<const ImgType*>& vec);
01646   
01648     template<class ImgType>
01649     ImgType* combineImages(const std::vector<ImgType*>& vec) {
01650       return const_cast<ImgType*>(combineImages(reinterpret_cast<const std::vector<const ImgType*>&>(vec)));
01651     }
01652   
01653     /* {{{   deepCopyChannel */
01655     template<class T>
01656     inline void deepCopyChannel(const Img<T> *src, int srcC, Img<T> *dst, int dstC){
01657       FUNCTION_LOG("");
01658       ICLASSERT_RETURN( src && dst );
01659       ICLASSERT_RETURN( src->getSize() == dst->getSize() );
01660       ICLASSERT_RETURN( src->validChannel(srcC) );
01661       ICLASSERT_RETURN( dst->validChannel(dstC) );
01662       icl::core::copy<T>(src->getData(srcC),src->getData(srcC)+src->getDim(),dst->getData(dstC));
01663     }
01664   
01665     /* }}} */
01666    
01667     /* {{{   convertChannel */
01668   
01670 
01678     template<class S,class D> 
01679     inline void convertChannel(const Img<S> *src, int srcC, Img<D> *dst, int dstC){
01680       FUNCTION_LOG("");
01681       ICLASSERT_RETURN( src && dst );
01682       ICLASSERT_RETURN( src->getSize() == dst->getSize() );
01683       ICLASSERT_RETURN( src->validChannel(srcC) );
01684       ICLASSERT_RETURN( dst->validChannel(dstC) );
01685       icl::core::convert<S,D>(src->getData(srcC),src->getData(srcC)+src->getDim(),dst->getData(dstC));
01686     }
01687   
01688     /* }}} */
01689   
01690     /* {{{   clearChannelROI */
01691   
01693 
01701     template<class T>
01702     inline void clearChannelROI(Img<T> *im, int c, T clearVal, const utils::Point &offs,
01703                                 const utils::Size &size) {
01704       FUNCTION_LOG("");
01705       ICLASSERT_RETURN( im );
01706   
01707       ImgIterator<T> it(im->getData(c),im->getSize().width,utils::Rect(offs,size));
01708       const ImgIterator<T> itEnd = ImgIterator<T>::create_end_roi_iterator(im->getData(c),
01709                                                                            im->getWidth(),
01710                                                                            utils::Rect(offs,size));
01711       std::fill(it,itEnd,clearVal);
01712     }
01713   
01715 #ifdef ICL_HAVE_IPP
01716 
01717     template <>
01718     inline void clearChannelROI(Img<icl8u> *im, int c, icl8u clearVal, const utils::Point &offs, 
01719                                 const utils::Size &size){
01720       FUNCTION_LOG("");
01721       ICLASSERT_RETURN( im );
01722       ippiSet_8u_C1R(clearVal,im->getROIData(c,offs),im->getLineStep(),size);
01723     }
01725     template <>
01726     inline void clearChannelROI(Img<icl16s> *im, int c, icl16s clearVal, const utils::Point &offs, 
01727                                 const utils::Size &size){
01728       FUNCTION_LOG("");
01729       ICLASSERT_RETURN( im );
01730       ippiSet_16s_C1R(clearVal,im->getROIData(c,offs),im->getLineStep(),size);
01731     }
01733     template <>
01734     inline void clearChannelROI(Img<icl32s> *im, int c, icl32s clearVal, 
01735                                 const utils::Point &offs, const utils::Size &size){
01736       FUNCTION_LOG("");
01737       ICLASSERT_RETURN( im );
01738       ippiSet_32s_C1R(clearVal,im->getROIData(c,offs),im->getLineStep(),size);
01739     }
01741     template <>
01742     inline void clearChannelROI(Img<icl32f> *im, int c, icl32f clearVal, 
01743                                 const utils::Point &offs, const utils::Size &size){
01744       FUNCTION_LOG("");
01745       ICLASSERT_RETURN( im );
01746       ippiSet_32f_C1R(clearVal,im->getROIData(c,offs),im->getLineStep(),size);
01747     }
01748 #endif
01749 
01751     /* }}} */
01752     
01754 
01755 #define CHECK_VALUES(src,srcC,srcOffs,srcSize,dst,dstC,dstOffs,dstSize) \
01756     FUNCTION_LOG("");                                                   \
01757     ICLASSERT_RETURN( src && dst );                                     \
01758     ICLASSERT_RETURN( srcSize == dstSize );                             \
01759     ICLASSERT_RETURN( src->validChannel(srcC) );                        \
01760     ICLASSERT_RETURN( dst->validChannel(dstC) );                        \
01761     ICLASSERT_RETURN( srcOffs.x >= 0 && srcOffs.y >= 0 && dstOffs.x >= 0 && dstOffs.y >= 0); \
01762     ICLASSERT_RETURN( srcOffs.x+srcSize.width <= src->getWidth() && srcOffs.y+srcSize.height <= src->getHeight() ); \
01763     ICLASSERT_RETURN( dstOffs.x+dstSize.width <= dst->getWidth() && dstOffs.y+dstSize.height <= dst->getHeight() );   
01764 
01765 
01769     /* {{{   deepCopyChannelROI */
01770   
01772 
01782     template <class T>
01783     inline void deepCopyChannelROI(const Img<T> *src, int srcC, const utils::Point &srcOffs,
01784                                    const utils::Size &srcSize,
01785                                    Img<T> *dst,int dstC, const utils::Point &dstOffs, 
01786                                    const utils::Size &dstSize) {
01787       CHECK_VALUES(src,srcC,srcOffs,srcSize,dst,dstC,dstOffs,dstSize);
01788       
01789       const ImgIterator<T> itSrc(const_cast<T*>(src->getData(srcC)),
01790                                  src->getSize().width,
01791                                  utils::Rect(srcOffs,srcSize));
01792       ImgIterator<T> itDst(dst->getData(dstC),dst->getSize().width,utils::Rect(dstOffs,dstSize));
01793       const ImgIterator<T> itSrcEnd = ImgIterator<T>::create_end_roi_iterator(src->getData(srcC),
01794                                                                               src->getWidth(),
01795                                                                               utils::Rect(srcOffs,srcSize));
01796       
01797       for(;itSrc != itSrcEnd;itSrc.incRow(),itDst.incRow()){
01798         icl::core::copy<T>(&*itSrc,&*itSrc+srcSize.width,&*itDst);
01799       }
01800     }
01801     
01802     /* }}} */
01803   
01804     /* {{{   convertChannelROI */
01805   
01808 
01822     template <class S,class D>
01823     inline void convertChannelROI(const Img<S> *src, int srcC, const utils::Point &srcOffs,
01824                                   const utils::Size &srcROISize,
01825                                   Img<D> *dst,int dstC, const utils::Point &dstOffs, 
01826                                   const utils::Size &dstROISize)
01827     {
01828       FUNCTION_LOG("");
01829       CHECK_VALUES(src,srcC,srcOffs,srcROISize,dst,dstC,dstOffs,dstROISize);
01830       
01831       const ImgIterator<S> itSrc(const_cast<S*>(src->getData(srcC)),
01832                                  src->getSize().width,
01833                                  utils::Rect(srcOffs,srcROISize));
01834       ImgIterator<D> itDst(dst->getData(dstC),dst->getSize().width,
01835                            utils::Rect(dstOffs,dstROISize));
01836       const ImgIterator<S> itSrcEnd = ImgIterator<S>::create_end_roi_iterator(src->getData(srcC),
01837                                                                               src->getWidth(),
01838                                                                               utils::Rect(srcOffs,srcROISize));
01839       for(;itSrc != itSrcEnd ;itSrc.incRow(),itDst.incRow()){
01840         icl::core::convert<S,D>(&*itSrc,&*itSrc+srcROISize.width,&*itDst);
01841       }
01842     }
01843     
01845   
01846     /* }}} */
01847   
01848     /* {{{   scaledCopyChannelROI */
01849   
01852 
01865     template<class T> ICLCore_API
01866     void scaledCopyChannelROI(const Img<T> *src, int srcC,
01867                               const utils::Point &srcOffs, 
01868                               const utils::Size &srcSize,
01869                               Img<T> *dst,int dstC, 
01870                               const utils::Point &dstOffs,
01871                               const utils::Size &dstSize,
01872                               scalemode eScaleMode);
01873   
01874     /* }}} */
01875   
01876     /* {{{   flippedCopyChannelROI */
01877   
01879 
01891     template <class T> ICLCore_API
01892     void flippedCopyChannelROI(axis eAxis,
01893                                const Img<T> *src,int srcC, const utils::Point &srcOffs,
01894                                const utils::Size &srcSize,
01895                                Img<T> *dst,int dstC, const utils::Point &dstOffs, 
01896                                const utils::Size &dstSize);
01897 
01898     
01900 
01914     ICLCore_API void flippedCopy(axis eAxis, const ImgBase *poSrc, ImgBase **ppoDst = 0);
01915   
01917 
01934     ICLCore_API void flippedCopyROI(axis eAxis, const ImgBase *poSrc, ImgBase **ppoDst = 0);
01935     /* }}} */
01936   
01937     /* }}} */
01938   } // namespace core
01939 } //namespace icl
01940 
01941 #undef CHECK_VALUES
01942 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines