passing multi dimensional array from cffi to c

221 views
Skip to first unread message

Prashant Saxena

unread,
May 7, 2016, 7:19:30 AM5/7/16
to python-cffi
Hi,

I have a numpy array like this:
buffer = numpy.ones((height,width,3), dtype=numpy.uint8)
a structure that represent a pixel like this:
typedef struct{
   
unsigned char r, g, b;
} pixel;
Now how do pass this array from python-cffi to a c function where I can easily set values. Something like this:
buffer[23][34].r = 255;
buffer
[23][34].g = 0;
buffer
[23][34].b = 255;

Regards
Prashant



Armin Rigo

unread,
May 7, 2016, 7:25:41 AM5/7/16
to pytho...@googlegroups.com
Hi,

On 7 May 2016 at 13:19, Prashant Saxena <anima...@gmail.com> wrote:
> Now how do pass this array from python-cffi to a c function where I can
> easily set values. Something like this:
> buffer[23][34].r = 255;
> buffer[23][34].g = 0;
> buffer[23][34].b = 255;

NumPy arrays support the buffer interface, so you can use ffi.from_buffer():
http://cffi.readthedocs.io/en/latest/ref.html#ffi-buffer-ffi-from-buffer

Example: x=lib.somefunction(ffi.from_buffer(my_numpy_array))


A bientôt,

Armin

Prashant Saxena

unread,
May 7, 2016, 7:46:11 AM5/7/16
to python-cffi, ar...@tunes.org
Thanks Armin,

Could you please let me know the definition of 'somefunction' in C in this case?
I tried this way:
void somefunction(unsigned char *buffer){
pixel *p;
p = (pixel*)buffer[0][0];
p->r, p->g, p->b
...
}

Prashant

Armin Rigo

unread,
May 8, 2016, 3:10:34 AM5/8/16
to pytho...@googlegroups.com
Hi Prashant,

On 7 May 2016 at 13:46, Prashant Saxena <anima...@gmail.com> wrote:
> Could you please let me know the definition of 'somefunction' in C in this
> case?

That's a C question. It is a bit outside the scope of this mailing
list, but let me try.

> void somefunction(unsigned char *buffer){
> pixel *p;
> p = (pixel*)buffer[0][0];
> p->r, p->g, p->b
> ...
> }

An "unsigned char *" argument is a pointer to the start of the data,
which is a contiguous array, "rgbrgbrgbrgb...". There is no
information about the fact that this was originally organized as a 2D
matrix. If you need this, you need to pass extra arguments to the C
function, like "int width, int height". Then you access the pixel at
(x, y) with this kind of code:

pixel *corner, *line_start, *p;
corner = (pixel *)buffer;
line_start = corner + y * width;
p = line_start + x;


A bientôt,

Armin.
Reply all
Reply to author
Forward
0 new messages