fixed some more compile bugs (including Python bindings)
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Tue, 22 Oct 2013 19:34:16 +0000 (23:34 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Tue, 22 Oct 2013 19:34:16 +0000 (23:34 +0400)
cmake/OpenCVDetectPython.cmake
modules/core/include/opencv2/core/mat.hpp
modules/core/src/matrix.cpp
modules/core/src/ocl.cpp
modules/core/src/umatrix.cpp
modules/python/src2/cv2.cpp

index 6f3ce4e..7f258dc 100644 (file)
@@ -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)
 
index d25919d..662da51 100644 (file)
@@ -346,6 +346,7 @@ struct CV_EXPORTS UMatData
 
     int flags;
     void* handle;
+    void* userdata;
 };
 
 
index d0d18f7..1493e1f 100644 (file)
@@ -80,8 +80,10 @@ public:
     void deallocate(UMatData* u) const
     {
         if(u)
+        {
             fastFree(u->origdata);
-        delete u;
+            delete u;
+        }
     }
 
     void map(UMatData*, int) const
index 114cb55..5adac67 100644 (file)
@@ -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_uint, int>(CL_DEVICE_ADDRESS_BITS) : 0; }
 
 bool Device::available() const
-{ return p ? p->getProp<cl_bool, bool>(CL_DEVICE_AVAILABLE) : 0; }
+{ return p ? p->getBoolProp(CL_DEVICE_AVAILABLE) : false; }
 
 bool Device::compilerAvailable() const
-{ return p ? p->getProp<cl_bool, bool>(CL_DEVICE_COMPILER_AVAILABLE) : 0; }
+{ return p ? p->getBoolProp(CL_DEVICE_COMPILER_AVAILABLE) : false; }
 
 bool Device::linkerAvailable() const
-{ return p ? p->getProp<cl_bool, bool>(CL_DEVICE_LINKER_AVAILABLE) : 0; }
+{ return p ? p->getBoolProp(CL_DEVICE_LINKER_AVAILABLE) : false; }
 
 int Device::doubleFPConfig() const
 { return p ? p->getProp<cl_device_fp_config, int>(CL_DEVICE_DOUBLE_FP_CONFIG) : 0; }
@@ -1497,10 +1506,10 @@ int Device::halfFPConfig() const
 { return p ? p->getProp<cl_device_fp_config, int>(CL_DEVICE_HALF_FP_CONFIG) : 0; }
 
 bool Device::endianLittle() const
-{ return p ? p->getProp<cl_bool, bool>(CL_DEVICE_ENDIAN_LITTLE) : 0; }
+{ return p ? p->getBoolProp(CL_DEVICE_ENDIAN_LITTLE) : false; }
 
 bool Device::errorCorrectionSupport() const
-{ return p ? p->getProp<cl_bool, bool>(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_exec_capabilities, int>(CL_DEVICE_EXECUTION_CAPABILITIES) : 0; }
@@ -1524,10 +1533,10 @@ int Device::localMemType() const
 { return p ? p->getProp<cl_device_local_mem_type, int>(CL_DEVICE_LOCAL_MEM_TYPE) : 0; }
 
 bool Device::hostUnifiedMemory() const
-{ return p ? p->getProp<cl_bool, bool>(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_bool, bool>(CL_DEVICE_IMAGE_SUPPORT) : 0; }
+{ return p ? p->getBoolProp(CL_DEVICE_IMAGE_SUPPORT) : false; }
 
 size_t Device::image2DMaxWidth() const
 { return p ? p->getProp<size_t, size_t>(CL_DEVICE_IMAGE2D_MAX_WIDTH) : 0; }
index 996138e..df3b87c 100644 (file)
@@ -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;
index 03328ee..ba6dad8 100644 (file)
@@ -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<npy_intp> _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<>