#include #include namespace icl { // {{{ C++ fallback ThreshOp classes template class ThreshOpLTVal { // {{{ open public: ThreshOpLTVal (T t, T v) : threshold(t), value(v) {} inline T operator()(T val) const { if (val < threshold) return value; return val; } private: T threshold; T value; }; // }}} template class ThreshOpGTVal { // {{{ open public: ThreshOpGTVal (T t, T v) : threshold(t), value(v) {} inline T operator()(T val) const { if (val > threshold) return value; return val; } private: T threshold; T value; }; // }}} template class ThreshOpLTGTVal { // {{{ open public: ThreshOpLTGTVal(T tLow, T vLow, T tUp, T vUp) : tLow(tLow), tUp(tUp), vLow(vLow), vUp(vUp) {} inline T operator()(T val) const { if (val < tLow) return vLow; if (val > tUp) return vUp; return val; } private: T tLow, tUp; T vLow, vUp; }; // }}} // }}} // {{{ C++ fallback threshold function for all threshold operations template inline void fallbackThreshold(const Img *src, Img *dst, const ThresholdOp &threshold) { ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( src->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src->getChannels() == dst->getChannels() ); for(int c=src->getChannels()-1; c >= 0; --c) { ConstImgIterator itSrc = src->getROIIterator(c); ImgIterator itDst = dst->getROIIterator(c); for(;itSrc.inRegion(); ++itSrc, ++itDst){ *itDst = threshold(*itSrc); } } } // }}} #define ICL_INSTANTIATE_ALL_IPP_DEPTHS \ ICL_INSTANTIATE_DEPTH(8u) \ ICL_INSTANTIATE_DEPTH(16s) \ ICL_INSTANTIATE_DEPTH(32f) #define ICL_INSTANTIATE_ALL_FB_DEPTHS \ ICL_INSTANTIATE_DEPTH(32s) \ ICL_INSTANTIATE_DEPTH(64f) #ifdef WITH_IPP_OPTIMIZATION // {{{ ippi-function call templates template inline void ippiThresholdCall_1T(const Img *src, Img *dst, T t){ // {{{ open ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( src->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src->getChannels() == dst->getChannels() ); for (int c=src->getChannels()-1; c >= 0; --c) { ippiFunc (src->getROIData (c), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), t); } } // }}} template inline void ippiThresholdCall_2T(const Img *src, Img *dst, T t1, T t2){ // {{{ open ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( src->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src->getChannels() == dst->getChannels() ); for (int c=src->getChannels()-1; c >= 0; --c) { ippiFunc (src->getROIData (c), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), t1, t2); } } // }}} template inline void ippiThresholdCall_4T(const Img *src, Img *dst, T t1,T t2, T t3, T t4){ // {{{ open ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( src->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src->getChannels() == dst->getChannels() ); for (int c=src->getChannels()-1; c >= 0; --c) { ippiFunc (src->getROIData (c), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), t1,t2,t3,t4); } } // }}} // }}} // {{{ function specializations without Val postfix #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::lt(const Img ## T *src,Img ## T *dst, icl ## T t){\ ippiThresholdCall_1T (src, dst, t);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::gt(const Img ## T *src,Img ## T *dst, icl ## T t){\ ippiThresholdCall_1T (src, dst, t);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltgt(const Img ## T *src,Img ## T *dst, icl ## T tMin, icl ## T tMax){\ ippiThresholdCall_4T (src, dst, tMin,tMin, tMax,tMax);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH // }}} // {{{ function specializations with Val postfix #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltVal(const Img ## T *src,Img ## T *dst, icl ## T t, icl ## T val){\ ippiThresholdCall_2T (src, dst, t, val);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::gtVal(const Img ## T *src,Img ## T *dst, icl ## T t, icl ## T val){\ ippiThresholdCall_2T (src, dst, t, val);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltgtVal(const Img ## T *src,Img ## T *dst, icl ## T tMin,icl ## T minVal, icl ## T tMax,icl ## T maxVal){\ ippiThresholdCall_4T (src, dst, tMin, minVal, tMax, maxVal);} ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_DEPTH // }}} #endif // {{{ function specializations without Val postfix (fallback) /* We just use the appropriate *Val functions, because there is no performance gain implementing a specialised variant */ #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::lt(const Img ## T *src, Img ## T *dst, icl ## T t){\ Threshold::ltVal(src, dst, t, t);} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::gt(const Img ## T *src, Img ## T *dst, icl ## T t){\ Threshold::gtVal(src, dst, t, t);} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltgt(const Img ## T *src, Img ## T *dst, icl ## T tMin, icl ## T tMax){\ Threshold::ltgtVal(src, dst, tMin,tMin, tMax,tMax);} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH // }}} // {{{ function specializations with Val postfix (fallback) #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltVal(const Img ##T *src, Img ## T *dst, icl ## T t, icl ## T val){\ fallbackThreshold (src, dst, ThreshOpLTVal(t,val));} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::gtVal(const Img ##T *src, Img ## T *dst, icl ## T t, icl ## T val){\ fallbackThreshold (src, dst, ThreshOpGTVal(t,val));} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Threshold::ltgtVal(const Img ## T *src, Img ## T *dst, icl ## T tMin, icl ## T minVal, icl ##T tMax, icl ## T maxVal){\ fallbackThreshold (src, dst, ThreshOpLTGTVal(tMin,minVal,tMax,maxVal));} #ifdef WITH_IPP_OPTIMIZATION ICL_INSTANTIATE_ALL_FB_DEPTHS #else ICL_INSTANTIATE_ALL_DEPTHS #endif #undef ICL_INSTANTIATE_DEPTH // }}} #undef ICL_INSTANTIATE_ALL_IPP_DEPTHS #undef ICL_INSTANTIATE_ALL_FB_DEPTHS // {{{ ImgBase* versions #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: lt(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(t)); break; void Threshold::lt(const ImgBase *poSrc, ImgBase **ppoDst, icl32f t) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: gt(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(t)); break; void Threshold::gt(const ImgBase *poSrc, ImgBase **ppoDst, icl32f t) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: ltgt(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(tMin), Cast::cast(tMax)); break; void Threshold::ltgt(const ImgBase *poSrc, ImgBase **ppoDst, icl32f tMin, icl32f tMax) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: ltVal(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(t), Cast::cast(val)); break; void Threshold::ltVal(const ImgBase *poSrc, ImgBase **ppoDst, icl32f t, icl32f val) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: gtVal(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(t), Cast::cast(val)); break; void Threshold::gtVal(const ImgBase *poSrc, ImgBase **ppoDst, icl32f t, icl32f val) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: ltgtVal(poSrc->asImg(), (*ppoDst)->asImg(), Cast::cast(tMin),\ Cast::cast(minVal), Cast::cast(tMax), Cast::cast(maxVal));break; void Threshold::ltgtVal(const ImgBase *poSrc, ImgBase **ppoDst, icl32f tMin, icl32f minVal, icl32f tMax, icl32f maxVal) // {{{ open { if (!Filter::prepare (ppoDst, poSrc)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_DEPTH; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} } // namespace icl