#include #include #include #include namespace icl{ namespace{ template inline T* deepcopy(const T*src, int dim){ T *cpy = new T[dim]; std::copy(src,src+dim,cpy); return cpy; } template inline T* save_deepcopy(const T*src, int dim){ if(!src || !dim) return 0; T *cpy = new T[dim]; std::copy(src,src+dim,cpy); return cpy; } bool is_convertable_to_int (float *data, int len){ // tests if an element of the given float* has decimals // if it does: return 0, else 1 for(int i=0;i 0,InvalidSizeException(__FUNCTION__)); if(deepCopy){ idata = deepcopy(data,getDim()); }else{ idata = data; } isnull = !idata; } ConvolutionKernel::ConvolutionKernel(float *data, const Size &size, bool deepCopy) throw (InvalidSizeException): size(size),fdata(0),idata(0),factor(factor),isnull(false),owned(deepCopy),ft(custom){ ICLASSERT_THROW(getDim() > 0,InvalidSizeException(__FUNCTION__)); if(deepCopy){ fdata = deepcopy(data,getDim()); }else{ fdata = data; } isnull = !fdata; } ConvolutionKernel::ConvolutionKernel(fixedType t, bool useFloats): size(t>9 ? Size(5,5) : Size(3,3)),fdata(0),isnull(false),owned(false),ft(t){ switch(t){ case gauss3x3: idata = GAUSS_3x3; break; case gauss5x5: idata = GAUSS_5x5; break; case sobelX3x3: idata = SOBEL_X_3x3; break; case sobelX5x5: idata = SOBEL_X_5x5; break; case sobelY3x3: idata = SOBEL_Y_3x3; break; case sobelY5x5: idata = SOBEL_Y_5x5; break; case laplace3x3: idata = LAPLACE_3x3; break; case laplace5x5: idata = LAPLACE_5x5; break; default: throw ICLException("invalid fixed convolution kernel type"); } factor = *idata++; if(useFloats){ toFloat(); } } ConvolutionKernel &ConvolutionKernel::operator=(const ConvolutionKernel &other){ if(owned){ ICL_DELETE(idata); ICL_DELETE(fdata); } size = other.size; fdata = 0; idata = 0; factor = other.factor; isnull = other.isnull; owned = other.owned; ft = other.ft; if(owned){ if(other.fdata)fdata = deepcopy(other.fdata,getDim()); if(other.idata)idata = deepcopy(other.idata,getDim()); }else{ fdata = other.fdata; idata = other.idata; } return *this; } ConvolutionKernel::~ConvolutionKernel() { if(owned){ ICL_DELETE(idata); ICL_DELETE(fdata); } } void ConvolutionKernel::toFloat(){ if(idata && !fdata){ fdata = new float[getDim()]; std::transform(idata,idata+getDim(),fdata,std::bind2nd(std::divides(),factor)); if(owned){ ICL_DELETE(idata); }else{ idata = 0; } owned = true; factor = 1.0; } } void ConvolutionKernel::toInt(bool force){ if(fdata && !idata){ if(force || is_convertable_to_int(fdata,getDim())){ idata = new int[getDim()]; std::copy(fdata,fdata+getDim(),idata); if(owned){ ICL_DELETE(fdata); }else{ fdata = 0; } owned = true; } } } void ConvolutionKernel::detach(){ if(!owned){ if(idata) idata = deepcopy(idata,getDim()); if(fdata) fdata = deepcopy(fdata,getDim()); } } }