#include namespace icl{ template T interpolate_pixel_nn(float x, float y, const Channel &src){ if(x < 0) return T(0); return src(round(x),round(y)); } template T interpolate_pixel_lin(float x, float y, const Channel &src){ float fX0 = x - floor(x), fX1 = 1.0 - fX0; float fY0 = y - floor(y), fY1 = 1.0 - fY0; int xll = (int) x; int yll = (int) y; const T* pLL = &src(xll,yll); float a = *pLL; // a b float b = *(++pLL); // c d pLL += src.getWidth(); float d = *pLL; float c = *(--pLL); return fX1 * (fY1*a + fY0*c) + fX0 * (fY1*b + fY0*d); } template &src)> static inline void apply_warp_2(const Channel32f warpMap[2], const Channel &src, Channel &dst, const Size &size){ for(int x=0;x static void apply_warp(const Channel32f warpMap[2], const Img&src, Img &dst, scalemode mode){ for(int c=0;c s = src[c]; Channel d = dst[c]; if(mode == interpolateNN){ apply_warp_2 >(warpMap,s,d,s.getSize()); }else if(mode == interpolateLIN){ apply_warp_2 >(warpMap,s,d,s.getSize()); }else{ ERROR_LOG("region average interpolation mode does not work here!"); return; } } } #ifdef HAVE_IPP template<> void apply_warp(const Channel32f warpMap[2], const Img &src, Img &dst, scalemode mode){ for(int c=0;c void apply_warp(const Channel32f warpMap[2], const Img &src, Img &dst, scalemode mode){ for(int c=0;c and #endif void prepare_warp_table_inplace(Img32f &warpMap){ const Rect r = warpMap.getImageRect(); Channel32f cs[2]; warpMap.extractChannels(cs); const Size size = warpMap.getSize(); for(int x=0;xhasFullROI()){ ERROR_LOG("warp op does currently not support ROI"); return; } if(!UnaryOp::prepare(dst,src->getDepth(),src->getSize(), src->getFormat(),src->getChannels(), src->getROI(),src->getTime())){ ERROR_LOG("unable to prepare destination image (returning)"); return; } Channel32f cwm[2]; if(src->getSize() != m_warpMap.getSize()){ if(m_allowWarpMapScaling){ if(m_scaledWarpMap.getSize() != src->getSize()){ m_scaledWarpMap.setSize(src->getSize()); m_warpMap.scaledCopy(&m_scaledWarpMap); prepare_warp_table_inplace(m_scaledWarpMap); } m_scaledWarpMap.extractChannels(cwm); }else{ ERROR_LOG("warp map size and image size are not equal\n" "warp map can be scaled using\n" "setAllowWarpMapScaling(true)"); return; } }else{ m_warpMap.extractChannels(cwm); } switch(src->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D: \ apply_warp(cwm,*src->asImg(), \ *(*dst)->asImg(),m_scaleMode); \ break; ICL_INSTANTIATE_ALL_DEPTHS; default: ICL_INVALID_DEPTH; #undef ICL_INSTANTIATE_DEPTH } } }