[Cython] 2d buffer interface with aligned data

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


On 07/17/2012 06:55 PM, Dag Sverre Seljebotn wrote:
> 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]

Sorry; shape = [3, 2] to match your example.

Dag

> 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