[Numpy-discussion] "aligned" matrix / ctypes

Robert Kern robert.kern@gmail....
Wed Apr 23 16:02:44 CDT 2008


On Wed, Apr 23, 2008 at 2:10 PM, Zachary Pincus <zachary.pincus@yale.edu> wrote:
> Hello all,
>
>  I need to allocate a numpy array that I will then pass to a camera
>  driver (via ctypes) so that the driver can fill the array with pixels.
>  The catch is that the driver requires that rows of pixels start at 4-
>  byte boundaries.
>
>  The sample C++ code given for allocating memory for this is (pixels
>  are unsigned shorts):
>
>  // Two bytes for each pixel, then round
>  // up to the next multiple of four.
>  long width_bytes = ( ( 2 * width_pixels ) + 3 ) & -4;
>  long allocated_size = width_bytes * height;
>  unsigned char* image_data = new unsigned char[allocated_size];
>  I could make an empty uint8 numpy array of the required shape
>  (allocated_size,) and adjust its dtype, shape, and strides to get the
>  desired result. I'd then feed the array's ctypes data attribute to the
>  driver to get filled in. Alternately I could allocate the data buffer
>  via ctypes and then construct an array around it.

Note that the approach above doesn't ensure that the first row is
correctly aligned. It just assumes that the allocator will always
start a new block aligned at 4 bytes (which may be reasonable for the
platforms you are targetting). Ignoring that issue for a moment, the
way to make sure that the rows are aligned is very similar to how you
do it in C. Round up the row length, make an array with the larger
dimensions (height,width_pixels+width_pixels%2), then slice out
[:,:width_pixels].

To solve the initial alignment, you overallocate a 1D array by 3 bytes
and find the offset from the allocated initial address which is
correctly aligned. Slice out [:allocated_size] portion of this,
.view() it as uint16, reshape it to
(height,width_pixels+width_pixels%2), then slice out
[:,:width_pixels].

>  Is either option better? How does one construct a numpy array around a
>  ctypes memory object? Can the array "take over" the memory management
>  for the buffer?

Whenever possible, I try to get numpy to do the allocating. That saves
many headaches. It is possible to do otherwise, but let's cover that
only if you need it.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
 -- Umberto Eco


More information about the Numpy-discussion mailing list