struct memtrack_t {
PyObject_HEAD
+ int owner;
void *ptr;
+ int freeptr;
Py_ssize_t size;
+ PyObject *backing;
+ CvArr *backingmat;
};
struct iplimage_t {
{
cvmatnd_t *pc = (cvmatnd_t*)self;
Py_DECREF(pc->data);
+ cvFree(&pc->a);
PyObject_Del(self);
}
/* memtrack */
+/* Motivation for memtrack is when the storage for a Mat is an array or buffer
+object. By setting 'data' to be a memtrack, can deallocate the storage at
+object destruction.
+
+For array objects, 'backing' is the actual storage object. memtrack holds the reference,
+then DECREF's it at dealloc.
+
+For MatND's, we need to cvDecRefData() on release, and this is what field 'backingmat' is for.
+
+If freeptr is true, then a straight cvFree() of ptr happens.
+
+*/
+
+
static void memtrack_dealloc(PyObject *self)
{
memtrack_t *pi = (memtrack_t*)self;
- // printf("===> memtrack_dealloc %p!\n", pi->ptr);
- cvFree(&pi->ptr);
+ if (pi->backing)
+ Py_DECREF(pi->backing);
+ if (pi->backingmat)
+ cvDecRefData(pi->backingmat);
+ if (pi->freeptr)
+ cvFree(&pi->ptr);
PyObject_Del(self);
}
memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
size_t gap = mat->data.ptr - (uchar*)mat->refcount;
o->ptr = mat->refcount;
+ o->owner = __LINE__;
+ o->freeptr = true;
o->size = gap + mat->rows * mat->step;
+ o->backing = NULL;
+ o->backingmat = NULL;
PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)gap, mat->rows * mat->step);
if (data == NULL)
return NULL;
#else
memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
o->ptr = mat->data.ptr;
+ o->owner = __LINE__;
+ o->freeptr = false;
o->size = mat->rows * mat->step;
+ o->backing = NULL;
+ o->backingmat = mat;
PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, mat->rows * mat->step);
if (data == NULL)
return NULL;
- Py_INCREF(o); // XXX - hack to prevent free of this foreign memory
#endif
m->data = data;
m->offset = 0;
memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
assert(ipl->imageDataOrigin == ipl->imageData);
o->ptr = ipl->imageDataOrigin;
+ o->owner = __LINE__;
+ o->freeptr = true;
o->size = ipl->height * ipl->widthStep;
+ o->backing = NULL;
+ o->backingmat = NULL;
PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size);
if (data == NULL)
return NULL;
return (PyObject*)cva;
}
-static PyObject *pythonize_CvMatND(cvmatnd_t *m)
+static PyObject *pythonize_CvMatND(cvmatnd_t *m, PyObject *backing = NULL)
{
//
// Need to make this CvMatND look like any other, with a Python
- // string as its data.
- // So copy the image data into a Python string object, then release
- // it.
+ // buffer object as its data.
//
CvMatND *mat = m->a;
PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->dim[0].size * mat->dim[0].step);
#else
memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type);
- o->ptr = cvPtr1D(mat, 0);
+ o->ptr = mat->data.ptr;
+ o->owner = __LINE__;
+ o->freeptr = false;
o->size = cvmatnd_size(mat);
+ Py_XINCREF(backing);
+ o->backing = backing;
+ o->backingmat = mat;
PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size);
+ Py_DECREF(o); // Now 'data' holds the only reference to 'o'
if (data == NULL)
return NULL;
#endif
m->data = data;
m->offset = 0;
- // cvDecRefData(mat); // Ref count should be zero here, so this is a release
return (PyObject*)m;
}
static PyObject *fromarray(PyObject *o, int allowND)
{
PyObject *ao = PyObject_GetAttrString(o, "__array_struct__");
+ PyObject *retval;
+
if ((ao == NULL) || !PyCObject_Check(ao)) {
PyErr_SetString(PyExc_TypeError, "object does not have array interface");
return NULL;
return (PyObject*)failmsg("cv.fromarray array can be 2D or 3D only, see allowND argument");
}
m->a->data.ptr = (uchar*)pai->data;
- return pythonize_foreign_CvMat(m);
+ retval = pythonize_foreign_CvMat(m);
} else {
int dims[CV_MAX_DIM];
int i;
cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
ERRWRAP(m->a = cvCreateMatND(pai->nd, dims, type));
m->a->data.ptr = (uchar*)pai->data;
- return pythonize_CvMatND(m);
+
+ retval = pythonize_CvMatND(m, ao);
}
+ Py_DECREF(ao);
+ return retval;
}
#endif