[Cython] 2d buffer interface with aligned data

Dag Sverre Seljebotn d.s.seljebotn at astro.uio.no
Tue Jul 17 18:55:40 CEST 2012


On 07/17/2012 05:38 PM, Christian Heimes wrote:
> Hello,
>
> I'm the author of https://bitbucket.org/tiran/smc.freeimage , a Cython
> wrapper of the FreeImage and LCMS libraries. FreeImage supports a broad
> variety of image formats and pixel formats from standard RGB up to RGBAF
> and complex numbers.
>
> Now I like to add support for buffer interface to my code to support
> zero-copy access of pixel data from NumPy. The wiki describes several
> ways to access objects through the new and old Python buffer interface.
> However I'm unable to find an example how to *implement* the buffer
> interface.

Read PEP 3118. Then implement __getbuffer__ and __releasebuffer__ in 
your cdef class (don't know if it's documented but you can see example 
in tests/run/buffer.pyx).


>
> Memory alignment makes the buffer interface more complicated, too.
> FreeImage stores the raw pixels non-contiguously. The lines are memory
> aligned (usually 32bit). For example a standard RGB image with 1 byte
> per pixel and size of 2*3 pixels has a memory layout of
>
>     BGRBGRxxBGRBGRxxBGRBGRxx
>
> on a little-endian machine. 'xx' are the two alignment bytes.

This is easily supported; above you would let

ndim = 2
strides = [8, 1]
shape = [2, 3]
itemsize = 1

The alignment bytes are skipped simply because shape[0] * itemsize < 
strides[0].

Dag

>
> Here is an excerpt from the FreeImage manual on how to access the raw
> pixel data. The above example has width: 2, height: 3, pitch: 8 and bpp: 3.
>
> unsigned width = FreeImage_GetWidth(dib);   // 2
> unsigned height = FreeImage_GetHeight(dib); // 3
> unsigned pitch = FreeImage_GetPitch(dib);   // 8
> unsigned bpp = FreeImage_GetBPP(dib);       // 3
>
> BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
> for(y = 0; y<  height; y++) {
>      BYTE *pixel = (BYTE*)bits;
>      for(x = 0; x<  width; x++) {
>          pixel[FI_RGBA_RED] = 128;
>          pixel[FI_RGBA_GREEN] = 128;
>          pixel[FI_RGBA_BLUE] = 128;
>          pixel += bpp;
>      }
>      // next line
>      bits += pitch;
> }
>
> Please help,
> Christian
> _______________________________________________
> cython-devel mailing list
> cython-devel at python.org
> http://mail.python.org/mailman/listinfo/cython-devel



More information about the cython-devel mailing list