1. Olivier Grisel
  2. pyleargist

Commits

Sebastien Campion  committed dfbef40

added array wrapper as detail in https://gist.github.com/1891866

  • Participants
  • Parent commits fceb519
  • Branches default
  • Tags 2.0.1

Comments (0)

Files changed (2)

File VERSION.txt

View file
-2.0.0
+2.0.1

File src/leargist.pyx

View file
+from libc.stdlib cimport free
+from cpython cimport PyObject, Py_INCREF
+
 cimport leargist
 import numpy as np 
 cimport numpy as np
 
 np.import_array()
 
+cdef class ArrayWrapper:
+    cdef void* data_ptr
+    cdef int size
+
+    cdef set_data(self, int size, void* data_ptr):
+        """ Set the data of the array
+        This cannot be done in the constructor as it must recieve C-level
+        arguments.
+        
+        Parameters:
+        -----------
+        size: int
+        Length of the array.
+        data_ptr: void*
+        Pointer to the data
+        
+        """
+        self.data_ptr = data_ptr
+        self.size = size
+
+    def __array__(self):
+        """ Here we use the __array__ method, that is called when numpy
+tries to get an array from the object."""
+        cdef np.npy_intp shape[1]
+        shape[0] = <np.npy_intp> self.size
+        # Create a 1D array, of length 'size'
+        ndarray = np.PyArray_SimpleNewFromData(1, shape,
+                                               np.NPY_FLOAT, self.data_ptr)
+        return ndarray
+
+    def __dealloc__(self):
+        """ Frees the array. This is called by Python when all the
+references to the object are gone. """
+        free(<void*>self.data_ptr)
+
 def color_gist(im, nblocks=4, orientations=(8, 8, 4)):
      """Compute the GIST descriptor of an RGB image"""
      scales = len(orientations)
      cdef int nb = nblocks
      cdef int s = scales
      cdef int* no = <int*>np.PyArray_DATA(orientations)
-     cdef float* gist = leargist.color_gist_scaletab(_c_color_image_t, nb, s, no)
+     cdef float* array = leargist.color_gist_scaletab(_c_color_image_t, nb, s, no)
+
+     size  = nblocks * nblocks * orientations.sum() * 3	       
          
-     cdef np.npy_intp dim = <np.npy_intp> nblocks * nblocks * orientations.sum() * 3
-     cdef np.ndarray g = np.PyArray_SimpleNewFromData(1, &dim, np.NPY_FLOAT, <void *> gist)
-     return g 
+     array_wrapper = ArrayWrapper()
+     array_wrapper.set_data(size, <void*> array)
+     ndarray = np.array(array_wrapper, copy=False)
+     # Assign our object to the 'base' of the ndarray object
+     #ndarray.base = <PyObject*> array_wrapper
+     ndarray.base =  array_wrapper
+     # Increment the reference count, as the above assignement was done in
+     # C, and Python does not know that there is this additional reference
+     Py_INCREF(array_wrapper)
+     return ndarray