From de521fc9fa10a5c17f6e830678d47346c55b880b Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 22 Oct 2013 23:34:16 +0400 Subject: [PATCH] fixed some more compile bugs (including Python bindings) --- cmake/OpenCVDetectPython.cmake | 3 + modules/core/include/opencv2/core/mat.hpp | 1 + modules/core/src/matrix.cpp | 4 +- modules/core/src/ocl.cpp | 23 ++++-- modules/core/src/umatrix.cpp | 3 +- modules/python/src2/cv2.cpp | 117 +++++++++++++++++++----------- 6 files changed, 100 insertions(+), 51 deletions(-) diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake index 6f3ce4e..7f258dc 100644 --- a/cmake/OpenCVDetectPython.cmake +++ b/cmake/OpenCVDetectPython.cmake @@ -12,7 +12,10 @@ if(WIN32 AND NOT PYTHON_EXECUTABLE) ) endforeach() endif() +find_host_package(PythonInterp 2.7) +if(NOT PYTHONINTERP_FOUND) find_host_package(PythonInterp "${MIN_VER_PYTHON}") +endif() unset(HAVE_SPHINX CACHE) diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index d25919d..662da51 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -346,6 +346,7 @@ struct CV_EXPORTS UMatData int flags; void* handle; + void* userdata; }; diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index d0d18f7..1493e1f 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -80,8 +80,10 @@ public: void deallocate(UMatData* u) const { if(u) + { fastFree(u->origdata); - delete u; + delete u; + } } void map(UMatData*, int) const diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 114cb55..5adac67 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -1394,6 +1394,15 @@ struct Device::Impl sz == sizeof(temp) ? _TpOut(temp) : _TpOut(); } + bool getBoolProp(cl_device_info prop) const + { + cl_bool temp = CL_FALSE; + size_t sz = 0; + + return clGetDeviceInfo(handle, prop, sizeof(temp), &temp, &sz) >= 0 && + sz == sizeof(temp) ? temp != 0 : false; + } + String getStrProp(cl_device_info prop) const { char buf[1024]; @@ -1479,13 +1488,13 @@ int Device::addressBits() const { return p ? p->getProp(CL_DEVICE_ADDRESS_BITS) : 0; } bool Device::available() const -{ return p ? p->getProp(CL_DEVICE_AVAILABLE) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_AVAILABLE) : false; } bool Device::compilerAvailable() const -{ return p ? p->getProp(CL_DEVICE_COMPILER_AVAILABLE) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_COMPILER_AVAILABLE) : false; } bool Device::linkerAvailable() const -{ return p ? p->getProp(CL_DEVICE_LINKER_AVAILABLE) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_LINKER_AVAILABLE) : false; } int Device::doubleFPConfig() const { return p ? p->getProp(CL_DEVICE_DOUBLE_FP_CONFIG) : 0; } @@ -1497,10 +1506,10 @@ int Device::halfFPConfig() const { return p ? p->getProp(CL_DEVICE_HALF_FP_CONFIG) : 0; } bool Device::endianLittle() const -{ return p ? p->getProp(CL_DEVICE_ENDIAN_LITTLE) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_ENDIAN_LITTLE) : false; } bool Device::errorCorrectionSupport() const -{ return p ? p->getProp(CL_DEVICE_ERROR_CORRECTION_SUPPORT) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_ERROR_CORRECTION_SUPPORT) : false; } int Device::executionCapabilities() const { return p ? p->getProp(CL_DEVICE_EXECUTION_CAPABILITIES) : 0; } @@ -1524,10 +1533,10 @@ int Device::localMemType() const { return p ? p->getProp(CL_DEVICE_LOCAL_MEM_TYPE) : 0; } bool Device::hostUnifiedMemory() const -{ return p ? p->getProp(CL_DEVICE_HOST_UNIFIED_MEMORY) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_HOST_UNIFIED_MEMORY) : false; } bool Device::imageSupport() const -{ return p ? p->getProp(CL_DEVICE_IMAGE_SUPPORT) : 0; } +{ return p ? p->getBoolProp(CL_DEVICE_IMAGE_SUPPORT) : false; } size_t Device::image2DMaxWidth() const { return p ? p->getProp(CL_DEVICE_IMAGE2D_MAX_WIDTH) : 0; } diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index 996138e..df3b87c 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -58,6 +58,7 @@ UMatData::UMatData(const MatAllocator* allocator) size = 0; flags = 0; handle = 0; + userdata = 0; } void UMatData::lock() @@ -554,7 +555,7 @@ Mat UMat::getMat(int accessFlags) const return hdr; } -void* UMat::handle(int accessFlags) const +void* UMat::handle(int /*accessFlags*/) const { if( !u ) return 0; diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 03328ee..ba6dad8 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -175,27 +175,27 @@ static PyObject* failmsgp(const char *fmt, ...) return 0; } -static size_t REFCOUNT_OFFSET = (size_t)&(((PyObject*)0)->ob_refcnt) + - (0x12345678 != *(const size_t*)"\x78\x56\x34\x12\0\0\0\0\0")*sizeof(int); - -static inline PyObject* pyObjectFromRefcount(const int* refcount) -{ - return (PyObject*)((size_t)refcount - REFCOUNT_OFFSET); -} - -static inline int* refcountFromPyObject(const PyObject* obj) -{ - return (int*)((size_t)obj + REFCOUNT_OFFSET); -} - class NumpyAllocator : public MatAllocator { public: - NumpyAllocator() {} + NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); } ~NumpyAllocator() {} - void allocate(int dims, const int* sizes, int type, int*& refcount, - uchar*& datastart, uchar*& data, size_t* step) + UMatData* allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const + { + UMatData* u = new UMatData(this); + u->refcount = 1; + u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o); + npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o); + for( int i = 0; i < dims - 1; i++ ) + step[i] = (size_t)_strides[i]; + step[dims-1] = CV_ELEM_SIZE(type); + u->size = sizes[0]*step[0]; + u->userdata = o; + return u; + } + + UMatData* allocate(int dims0, const int* sizes, int type, size_t* step) const { PyEnsureGIL gil; @@ -203,10 +203,10 @@ public: int cn = CV_MAT_CN(type); const int f = (int)(sizeof(size_t)/8); int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE : - depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT : - depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT : - depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT; - int i; + depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT : + depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT : + depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT; + int i, dims = dims0; cv::AutoBuffer _sizes(dims + 1); for( i = 0; i < dims; i++ ) _sizes[i] = sizes[i]; @@ -215,22 +215,58 @@ public: PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum); if(!o) CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims)); - refcount = refcountFromPyObject(o); - npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o); - for( i = 0; i < dims - (cn > 1); i++ ) - step[i] = (size_t)_strides[i]; - datastart = data = (uchar*)PyArray_DATA((PyArrayObject*) o); + return allocate(o, dims0, sizes, type, step); } - void deallocate(int* refcount, uchar*, uchar*) + bool allocate(UMatData* u, int accessFlags) const { - PyEnsureGIL gil; - if( !refcount ) - return; - PyObject* o = pyObjectFromRefcount(refcount); - Py_INCREF(o); - Py_DECREF(o); + return stdAllocator->allocate(u, accessFlags); + } + + void deallocate(UMatData* u) const + { + if(u) + { + PyEnsureGIL gil; + PyObject* o = (PyObject*)u->userdata; + Py_DECREF(o); + delete u; + } } + + void map(UMatData* u, int accessFlags) const + { + stdAllocator->map(u, accessFlags); + } + + void unmap(UMatData* u) const + { + stdAllocator->unmap(u); + } + + void download(UMatData* u, void* dstptr, + int dims, const size_t sz[], + const size_t srcofs[], const size_t srcstep[], + const size_t dststep[]) const + { + stdAllocator->download(u, dstptr, dims, sz, srcofs, srcstep, dststep); + } + + void upload(UMatData* u, const void* srcptr, int dims, const size_t sz[], + const size_t dstofs[], const size_t dststep[], + const size_t srcstep[]) const + { + stdAllocator->upload(u, srcptr, dims, sz, dstofs, dststep, srcstep); + } + + void copy(UMatData* usrc, UMatData* udst, int dims, const size_t sz[], + const size_t srcofs[], const size_t srcstep[], + const size_t dstofs[], const size_t dststep[], bool sync) const + { + stdAllocator->copy(usrc, udst, dims, sz, srcofs, srcstep, dstofs, dststep, sync); + } + + const MatAllocator* stdAllocator; }; NumpyAllocator g_numpyAllocator; @@ -400,16 +436,12 @@ static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo info) } m = Mat(ndims, size, type, PyArray_DATA(oarr), step); + m.u = g_numpyAllocator.allocate(o, ndims, size, type, step); - if( m.data ) + if( !needcopy ) { - m.refcount = refcountFromPyObject(o); - if (!needcopy) - { - m.addref(); // protect the original numpy array from deallocation - // (since Mat destructor will decrement the reference counter) - } - }; + Py_INCREF(o); + } m.allocator = &g_numpyAllocator; return true; @@ -427,8 +459,9 @@ PyObject* pyopencv_from(const Mat& m) ERRWRAP2(m.copyTo(temp)); p = &temp; } - p->addref(); - return pyObjectFromRefcount(p->refcount); + PyObject* o = (PyObject*)p->u->userdata; + Py_INCREF(o); + return o; } template<> -- 2.7.4