#include #include namespace icl { #define ICL_COMP_ZERO 0 #define ICL_COMP_NONZERO 255 // {{{ C++ fallback CompareOp classes template class CompareOpEq { // {{{ open public: inline icl8u operator()(T val1, T val2) const { return val1 == val2 ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} template class CompareOpLess { // {{{ open public: inline icl8u operator()(T val1, T val2) const { return val1 < val2 ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} template class CompareOpLessEq { // {{{ open public: inline icl8u operator()(T val1, T val2) const { return val1 <= val2 ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} template class CompareOpGreater { // {{{ open public: inline icl8u operator()(T val1, T val2) const { return val1 > val2 ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} template class CompareOpGreaterEq { // {{{ open public: inline icl8u operator()(T val1, T val2) const { return val1 >= val2 ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} template class CompareOpEqEps { // {{{ open public: inline icl8u operator()(T val1, T val2, T eps) const { return (std::abs(val1-val2) <= eps) ? ICL_COMP_NONZERO : ICL_COMP_ZERO; } }; // }}} // }}} // {{{ C++ fallback compare functions as templates template inline void fallbackCompare(const Img *src1, const Img *src2, Img8u *dst, const CompareOp &compare) // {{{ open { ICLASSERT_RETURN( src1 && src2 && dst ); ICLASSERT_RETURN( src1->getROISize() == src2->getROISize() ); ICLASSERT_RETURN( src1->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src1->getChannels() == src2->getChannels() ); ICLASSERT_RETURN( src1->getChannels() == dst->getChannels() ); for(int c=src1->getChannels()-1; c >= 0; --c) { ConstImgIterator itSrc1 = src1->getROIIterator(c); ConstImgIterator itSrc2 = src2->getROIIterator(c); ImgIterator itDst = dst->getROIIterator(c); for(;itSrc1.inRegion(); ++itSrc1, ++itSrc2, ++itDst){ *itDst = compare(*itSrc1,*itSrc2); } } } // }}} template inline void fallbackCompareC(const Img *src, T value, Img8u *dst, const CompareOp &compare) // {{{ 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) { ConstImgIterator itSrc = src->getROIIterator(c); ImgIterator itDst = dst->getROIIterator(c); for(;itSrc.inRegion(); ++itSrc, ++itDst){ *itDst = compare(*itSrc,value); } } } // }}} template inline void fallbackEqualEps(const Img *src1, const Img *src2, Img8u *dst, T eps) // {{{ open { ICLASSERT_RETURN( src1 && src2 && dst ); ICLASSERT_RETURN( src1->getROISize() == src2->getROISize() ); ICLASSERT_RETURN( src1->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src1->getChannels() == src2->getChannels() ); ICLASSERT_RETURN( src1->getChannels() == dst->getChannels() ); CompareOpEqEps compare; for(int c=src1->getChannels()-1; c >= 0; --c) { ConstImgIterator itSrc1 = src1->getROIIterator(c); ConstImgIterator itSrc2 = src2->getROIIterator(c); ImgIterator itDst = dst->getROIIterator(c); for(;itSrc1.inRegion(); ++itSrc1, ++itSrc2, ++itDst){ *itDst = compare(*itSrc1,*itSrc2,eps); } } } // }}} template inline void fallbackEqualEpsC(const Img *src, T value, Img8u *dst,T eps) // {{{ open { ICLASSERT_RETURN( src && dst ); ICLASSERT_RETURN( src->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src->getChannels() == dst->getChannels() ); CompareOpEqEps compare; 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 = compare(*itSrc,value,eps); } } } // }}} // }}} #ifdef WITH_IPP_OPTIMIZATION // {{{ ippi-function call templates template inline void ippiCompare(const Img *src1, const Img *src2, Img8u *dst, Compare::op cmpOp) // {{{ open { ICLASSERT_RETURN( src1 && src2 && dst ); ICLASSERT_RETURN( src1->getROISize() == src2->getROISize() ); ICLASSERT_RETURN( src1->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src1->getChannels() == src2->getChannels() ); ICLASSERT_RETURN( src1->getChannels() == dst->getChannels() ); for (int c=src1->getChannels()-1; c >= 0; --c) { ippiFunc (src1->getROIData (c), src1->getLineStep(), src2->getROIData (c), src2->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), (IppCmpOp) cmpOp); } } // }}} template inline void ippiCompareC(const Img *src, T value, Img8u *dst, Compare::op cmpOp) // {{{ 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(), value, dst->getROIData (c), dst->getLineStep(), dst->getROISize(),(IppCmpOp) cmpOp); } } // }}} // }}} // {{{ compare void Compare::compare(const Img8u *src1,const Img8u *src2,Img8u *dst, Compare::op cmpOp){ ippiCompare (src1,src2, dst, cmpOp); } void Compare::compare(const Img16s *src1,const Img16s *src2,Img8u *dst, Compare::op cmpOp){ ippiCompare (src1,src2, dst, cmpOp); } void Compare::compare(const Img32s *src1, const Img32s *src2, Img8u *dst, Compare::op cmpOp) // {{{ open { switch (cmpOp){ case Compare::compareEq: fallbackCompare (src1, src2, dst, CompareOpEq()); break; case Compare::compareLess: fallbackCompare (src1, src2, dst, CompareOpLess()); break; case Compare::compareLessEq: fallbackCompare (src1, src2, dst, CompareOpLessEq()); break; case Compare::compareGreater: fallbackCompare (src1, src2, dst, CompareOpGreater()); break; case Compare::compareGreaterEq: fallbackCompare (src1, src2, dst, CompareOpGreaterEq()); break; } } // }}} void Compare::compare(const Img32f *src1,const Img32f *src2,Img8u *dst, Compare::op cmpOp){ ippiCompare (src1,src2, dst, cmpOp); } void Compare::compare(const Img64f *src1, const Img64f *src2, Img8u *dst, Compare::op cmpOp) // {{{ open { switch (cmpOp){ case Compare::compareEq: fallbackCompare (src1, src2, dst, CompareOpEq()); break; case Compare::compareLess: fallbackCompare (src1, src2, dst, CompareOpLess()); break; case Compare::compareLessEq: fallbackCompare (src1, src2, dst, CompareOpLessEq()); break; case Compare::compareGreater: fallbackCompare (src1, src2, dst, CompareOpGreater()); break; case Compare::compareGreaterEq: fallbackCompare (src1, src2, dst, CompareOpGreaterEq()); break; } } // }}} void Compare::equalEps(const Img8u *src1,const Img8u *src2,Img8u *dst, icl8u eps) // {{{ open { ICLASSERT_RETURN( src1 && src2 && dst ); ICLASSERT_RETURN( src1->getROISize() == src2->getROISize() ); ICLASSERT_RETURN( src1->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src1->getChannels() == src2->getChannels() ); ICLASSERT_RETURN( src1->getChannels() == dst->getChannels() ); for (int c=src1->getChannels()-1; c >= 0; --c) { ippiAbsDiff_8u_C1R (src1->getROIData (c), src1->getLineStep(), src2->getROIData (c), src2->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize()); ippiThreshold_LTValGTVal_8u_C1IR (dst->getROIData (c), dst->getLineStep(), dst->getROISize(), eps, ICL_COMP_NONZERO, eps, ICL_COMP_ZERO); } } // }}} void Compare::equalEps(const Img32f *src1,const Img32f *src2,Img8u *dst, icl32f eps) // {{{ open { ICLASSERT_RETURN( src1 && src2 && dst ); ICLASSERT_RETURN( src1->getROISize() == src2->getROISize() ); ICLASSERT_RETURN( src1->getROISize() == dst->getROISize() ); ICLASSERT_RETURN( src1->getChannels() == src2->getChannels() ); ICLASSERT_RETURN( src1->getChannels() == dst->getChannels() ); for (int c=src1->getChannels()-1; c >= 0; --c) { ippiCompareEqualEps_32f_C1R (src1->getROIData (c), src1->getLineStep(), src2->getROIData (c), src2->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), eps); } } // }}} // }}} // {{{ compareC void Compare::compareC(const Img8u *src, icl8u value, Img8u *dst, Compare::op cmpOp){ ippiCompareC (src, value, dst, cmpOp); } void Compare::compareC(const Img16s *src, icl16s value, Img8u *dst, Compare::op cmpOp){ ippiCompareC (src, value, dst, cmpOp); } void Compare::compareC(const Img32s *src, icl32s value, Img8u *dst, Compare::op cmpOp) // {{{ open { switch (cmpOp){ case Compare::compareEq: fallbackCompareC (src, value, dst, CompareOpEq()); break; case Compare::compareLess: fallbackCompareC (src, value, dst, CompareOpLess()); break; case Compare::compareLessEq: fallbackCompareC (src, value, dst, CompareOpLessEq()); break; case Compare::compareGreater: fallbackCompareC (src, value, dst, CompareOpGreater()); break; case Compare::compareGreaterEq: fallbackCompareC (src, value, dst, CompareOpGreaterEq()); break; } } // }}} void Compare::compareC(const Img32f *src, icl32f value, Img8u *dst, Compare::op cmpOp){ ippiCompareC (src, value, dst, cmpOp); } void Compare::compareC(const Img64f *src, icl64f value, Img8u *dst, Compare::op cmpOp) // {{{ open { switch (cmpOp){ case Compare::compareEq: fallbackCompareC (src, value, dst, CompareOpEq()); break; case Compare::compareLess: fallbackCompareC (src, value, dst, CompareOpLess()); break; case Compare::compareLessEq: fallbackCompareC (src, value, dst, CompareOpLessEq()); break; case Compare::compareGreater: fallbackCompareC (src, value, dst, CompareOpGreater()); break; case Compare::compareGreaterEq: fallbackCompareC (src, value, dst, CompareOpGreaterEq()); break; } } // }}} void Compare::equalEpsC(const Img8u *src, icl8u value, Img8u *dst, icl8u eps) // {{{ 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) { ippiAbsDiffC_8u_C1R (src->getROIData (c), src->getLineStep(), dst->getROIData (c), dst->getLineStep(), dst->getROISize(), value); ippiThreshold_LTValGTVal_8u_C1IR (dst->getROIData (c), dst->getLineStep(), dst->getROISize(), eps, ICL_COMP_NONZERO, eps, ICL_COMP_ZERO); } } // }}} void Compare::equalEpsC(const Img32f *src, icl32f value, Img8u *dst, icl32f eps) // {{{ 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) { ippiCompareEqualEpsC_32f_C1R (src->getROIData (c), src->getLineStep(), value, dst->getROIData (c), dst->getLineStep(), dst->getROISize(), eps); } } // }}} //No IPP Functions available -> Fallback void Compare::equalEps(const Img16s *src1, const Img16s *src2,Img8u *dst, icl16s eps){ fallbackEqualEps(src1, src2, dst, eps); } void Compare::equalEps(const Img32s *src1, const Img32s *src2,Img8u *dst, icl32s eps){ fallbackEqualEps(src1, src2, dst, eps); } void Compare::equalEps(const Img64f *src1, const Img64f *src2,Img8u *dst, icl64f eps){ fallbackEqualEps(src1, src2, dst, eps); } void Compare::equalEpsC(const Img16s *src1, icl16s value,Img8u *dst, icl16s eps) { fallbackEqualEpsC(src1, value, dst, eps); } void Compare::equalEpsC(const Img32s *src1, icl32s value,Img8u *dst, icl32s eps) { fallbackEqualEpsC(src1, value, dst, eps); } void Compare::equalEpsC(const Img64f *src1, icl64f value,Img8u *dst, icl64f eps) { fallbackEqualEpsC(src1, value, dst, eps); } // }}} #else // NO IPP_OPTIMIZATION // {{{ C++ compare // {{{ open #define ICL_INSTANTIATE_DEPTH(T) \ void Compare::compare(const Img ## T *src1, const Img ## T *src2, Img8u *dst, Compare::op cmpOp){\ switch (cmpOp){\ case Compare::compareEq:\ fallbackCompare (src1, src2, dst, CompareOpEq()); break;\ case Compare::compareLess:\ fallbackCompare (src1, src2, dst, CompareOpLess()); break;\ case Compare::compareLessEq:\ fallbackCompare (src1, src2, dst, CompareOpLessEq()); break;\ case Compare::compareGreater:\ fallbackCompare (src1, src2, dst, CompareOpGreater()); break;\ case Compare::compareGreaterEq:\ fallbackCompare (src1, src2, dst, CompareOpGreaterEq()); break;\ }\ } ICL_INSTANTIATE_ALL_DEPTHS #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ void Compare::equalEps(const Img ## T *src1, const Img ## T *src2,Img8u *dst, icl ## T eps){\ fallbackEqualEps(src1, src2, dst, eps); } ICL_INSTANTIATE_ALL_DEPTHS #undef ICL_INSTANTIATE_DEPTH // }}} // {{{ C++ compareC // {{{ open #define ICL_INSTANTIATE_DEPTH(T) \ void Compare::compareC(const Img ## T *src, icl ## T value, Img8u *dst, Compare::op cmpOp){\ switch (cmpOp){\ case Compare::compareEq:\ fallbackCompareC (src, value, dst, CompareOpEq()); break;\ case Compare::compareLess:\ fallbackCompareC (src, value, dst, CompareOpLess()); break;\ case Compare::compareLessEq:\ fallbackCompareC (src, value, dst, CompareOpLessEq()); break;\ case Compare::compareGreater:\ fallbackCompareC (src, value, dst, CompareOpGreater()); break;\ case Compare::compareGreaterEq:\ fallbackCompareC (src, value, dst, CompareOpGreaterEq()); break;\ }\ } // }}} ICL_INSTANTIATE_ALL_DEPTHS #undef ICL_INSTANTIATE_DEPTH #define ICL_INSTANTIATE_DEPTH(T) \ void Compare::equalEpsC(const Img ## T *src1, icl ## T value,Img8u *dst, icl ## T eps){ \ fallbackEqualEpsC(src1, value, dst, eps);} ICL_INSTANTIATE_ALL_DEPTHS #undef ICL_INSTANTIATE_DEPTH // }}} #endif // {{{ ImgBase* functions #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: compare(poSrc1->asImg(),poSrc2->asImg(),(*ppoDst)->asImg(),cmpOp); break; void Compare::compare(const ImgBase *poSrc1, const ImgBase *poSrc2, ImgBase **ppoDst, Compare::op cmpOp) // {{{ open { ICLASSERT_RETURN( poSrc1 && poSrc2 && poSrc1->getDepth() == poSrc2->getDepth() ); ICLASSERT_RETURN( poSrc1->getROISize() == poSrc2->getROISize() ); ICLASSERT_RETURN( poSrc1->getChannels() == poSrc2->getChannels() ); if (!Filter::prepare (ppoDst, poSrc1, depth8u)) return; switch (poSrc1->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_FORMAT; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: equalEps(poSrc1->asImg(),poSrc2->asImg(), (*ppoDst)->asImg(),Cast::cast(eps)); break; void Compare::equalEps(const ImgBase *poSrc1, const ImgBase *poSrc2, ImgBase **ppoDst, icl32f eps) // {{{ open { ICLASSERT_RETURN( poSrc1 && poSrc2 && poSrc1->getDepth() == poSrc2->getDepth() ); ICLASSERT_RETURN( poSrc1->getROISize() == poSrc2->getROISize() ); ICLASSERT_RETURN( poSrc1->getChannels() == poSrc2->getChannels() ); if (!Filter::prepare (ppoDst, poSrc1, depth8u)) return; switch (poSrc1->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_FORMAT; break; }//?? } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: compareC(poSrc->asImg(),Cast::cast(value),(*ppoDst)->asImg(),cmpOp); break; void Compare::compareC(const ImgBase *poSrc, icl32f value, ImgBase **ppoDst, Compare::op cmpOp) // {{{ open { if (!Filter::prepare (ppoDst, poSrc, depth8u)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_FORMAT; break; } } #undef ICL_INSTANTIATE_DEPTH // }}} #define ICL_INSTANTIATE_DEPTH(T) \ case depth ## T: equalEpsC(poSrc->asImg(),Cast::cast(value),(*ppoDst)->asImg(),Cast::cast(eps)); break; void Compare::equalEpsC(const ImgBase *poSrc, icl32f value, ImgBase **ppoDst, icl32f eps) // {{{ open { if (!Filter::prepare (ppoDst, poSrc, depth8u)) return; switch (poSrc->getDepth()){ ICL_INSTANTIATE_ALL_DEPTHS default: ICL_INVALID_FORMAT; break; } } // }}} // }}} }