Re: [Pyrex] Allocating an array.array of a specific length in pyrex

Discussion in 'Python' started by Chris Lambacher, Jun 8, 2005.

  1. And we have a winner.

    For reference the final code is below.

    Thanks for your help,
    -Chris

    import array
    cdef extern from "Python.h":
    int PyObject_AsWriteBuffer(object obj, void **buffer, int *buffer_len)
    int PyObject_AsReadBuffer(object obj, void **buffer, int *buffer_len)
    object PyString_FromStringAndSize(char *, int)
    char *PyString_AsString(object obj)

    cdef int get_w_buffer(obj, unsigned char **data, int *length) except -1:
    cdef int result
    cdef void *vd
    # use a void *
    result = PyObject_AsWriteBuffer(obj, &vd, length)
    data[0] = <unsigned char *>vd
    return result

    cdef int get_r_buffer(obj, unsigned char **data, int *length) except -1:
    cdef int result
    cdef void *vd
    # use a void *
    result = PyObject_AsReadBuffer(obj, &vd, length)
    data[0] = <unsigned char *>vd
    return result

    def encode(int w, int h, in_a):
    cdef unsigned int pixels, a_off, str_off#, buffer_len
    cdef int res, inlen, buffer_len
    cdef unsigned char *in_str, *out_str

    res = get_r_buffer(in_a, &in_str, &inlen)
    if res:
    raise Exception, "Could not get a readable buffer from the input"


    pixels = w * h
    a = PyString_FromStringAndSize(NULL, pixels * 2)
    out_str = <unsigned char *> PyString_AsString(a)
    buffer_len = pixels * 2

    str_off = 0
    a_off = 0
    while a_off < buffer_len and str_off < inlen:
    out_str[a_off] = in_str[str_off]
    out_str[a_off+1] = (in_str[str_off+1] + in_str[str_off+4])/2
    out_str[a_off+2] = in_str[str_off+3]
    out_str[a_off+3] = (in_str[str_off+2] + in_str[str_off+5])/2

    str_off = str_off + 6
    a_off = a_off + 4

    return a



    On 6/8/05, Chris Lambacher <> wrote:
    > I replaced:
    > a = array.array('B', , [0] * (pixels * 2))
    > with:
    > a = PyString_FromStringAndSize(NULL, pixels * 2)
    >
    > and got:
    > C:\work\testing\plink_o_ip>python ycbycr.py
    > Traceback (most recent call last):
    > File "ycbycr.py", line 62, in ?
    > ycbycr = image2ycbycr(im)
    > File "ycbycr.py", line 38, in image2ycbycr
    > return _ycbycr.ycbcr2ycbycr(w, h, ycbcrim.tostring())
    > File "_ycbycr.pyx", line 42, in _ycbycr.ycbcr2ycbycr
    > res = get_w_buffer(a, &out_str, &buffer_len)
    > TypeError: Cannot use string as modifiable buffer
    >
    > Strings are not mutable so this is not going to work for me :(
    >
    > Is there a way to allocate a python buffer object and give that to
    > array.array or a string object?
    >
    > -Chris
    >
    > On 6/8/05, Chris Lambacher <> wrote:
    > > The memory is not temporary, I am passing it out as an array, thus the
    > > malloc/free route will require double allocation(once for malloc/free,
    > > once for array.array). I am not using string because when I tried to
    > > pass the data in as string, pyrex complained about the conversion.
    > > However, I could probably use the same PyObject_AsReadBuffer function
    > > call to get at the data passed in to the function as a string and then
    > > pass it out as a string as well using the interface suggested (
    > > PyString_FromStringAndSize and PyString_AsString ). Perhapse I need
    > > to substitute PyObject_AsWriteBuffer instead of PyString_AsString in
    > > order for my changes to get propegated back to the string object?
    > >
    > > -Chris
    > >
    > >
    > > On 6/8/05, Adam Langley <> wrote:
    > > > On 6/8/05, Chris Lambacher <> wrote:
    > > > > My question is, is there a better way to
    > > > > allocate the memory for the array.array object than:
    > > > > a = array.array('B', [0] * (pixels * 2))
    > > >
    > > > cdef unsigned char *buffer
    > > > temp_string = PyString_FromStringAndSize(NULL, length)
    > > > buffer = <unsigned char *> PyString_AsString(temp_string)
    > > >
    > > > That's one way to do it. But it looks like you just want an area of
    > > > memory so why not:
    > > >
    > > > cdef extern from "stdlib.h":
    > > > ctypedef unsigned long size_t
    > > > void *malloc(size_t size)
    > > > void free(void *mem)
    > > >
    > > > ?
    > > >
    > > > AGL
    > > >
    > > > --
    > > > Adam Langley
    > > > http://www.imperialviolet.org (+44) (0)7906 332512
    > > > PGP: 9113 256A CC0F 71A6 4C84 5087 CDA5 52DF 2CB6 3D60
    > > >

    > >
    > >
    > > --
    > > Christopher Lambacher
    > >
    > >

    >
    >
    > --
    > Christopher Lambacher
    >
    >



    --
    Christopher Lambacher
     
    Chris Lambacher, Jun 8, 2005
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Philipp
    Replies:
    21
    Views:
    741
    White Wolf
    Sep 17, 2003
  2. =?iso-8859-1?Q?Fran=E7ois?= Pinard

    Re: Pyrex without Python (was Re: calling Pyrex results from C)

    =?iso-8859-1?Q?Fran=E7ois?= Pinard, Jan 21, 2004, in forum: Python
    Replies:
    3
    Views:
    317
    A.M. Kuchling
    Jan 21, 2004
  3. Chris Lambacher
    Replies:
    0
    Views:
    389
    Chris Lambacher
    Jun 8, 2005
  4. Greg Ewing
    Replies:
    2
    Views:
    353
    Dieter Maurer
    Jun 29, 2006
  5. Rakesh Kumar
    Replies:
    5
    Views:
    686
    James Kanze
    Dec 21, 2007
Loading...

Share This Page