[Python-3000] PEP 368: Standard image protocol and class

Lino Mastrodomenico l.mastrodomenico at gmail.com
Sun Jul 1 18:59:09 CEST 2007


2007/7/1, BJörn Lindqvist <bjourne at gmail.com>:
> But I cannot see how it would solve the problem with to many image
> classes. The reason why PIL, PyGame and wxPython has different image
> classes is because each of them use different C functions for
> manipulating said image classes. These differences bubble up through
> the bindings and results in PIL exposing an Image, PyGame a Surface
> and wxPython a wxImage. The result is that if you want to use a PIL
> Image in say PyGame, you  still need to convert it.

Actually, this is not always true. :-)

For example it's entirely possible to have the *same* python RGBA
image considered as a SDL_Surface by SDL (the underlying library used
by pygame), as an ImagingMemoryInstance by the PIL C library and have
its buffer directly accepted by the OpenGL function glTexImage2D (with
a bit of care in the order of the corners passed to glTexCoord2f),
independently by who created the image in the first place.

This works because most C/C++ libraries give the possibility of
creating a native image struct/class using an existing memory buffer
(without copying it) and they support at least a subset of the modes
currently defined, with the exact byte order, padding, etc, specified
in the PEP (usually L and at least one of RGB or RGBA).

But you are right, the particular format specified in the PEP is not
always supported by existing the libraries, even when they support
that particular mode. Sometimes this can be fixed (e.g. PIL currently
uses by default 4 bytes per pixel for RGB images and has only
experimental support for 3 bytes per pixel, but its C library is
written by the same people that maintain the Python bindings, so they
can change it if they want) and sometimes it cannot be easily fixed
(e.g. a wxImage class will happily accept a RGB buffer as defined by
the PEP, but it has a funny memory arrangement for RGBA images that is
completely incompatible).

So I expect that each Python library that jumps on the PEP bandwagon
will have three levels of support for the modes listed:

  1) no support at all (e.g. most 3D libraries will probably never
accept CMYK images as textures); the user can explicitly convert the
image using "new_image = Image(new_mode, source=old_image)";

  2) limited support: they support a particular mode, but cannot
directly use the standard memory arrangement, so when they receive an
alien image object they convert it on the fly to their preferred byte
order and they do the reverse operation when a foreign library tries
to access the buffer property of their images (they may offer a
read-only buffer); this is not ideal, but it's better than the current
situation because it's transparent to the user and it requires only a
single memory copy/conversion instead of the two usually performed by
the current tostring/fromstring dance;

  3) full support: no conversion or memory copy ever necessary for the
exchange of images between two libraries if they both have full
support for a particular mode. Of course the Image class that I'm
writing and that I hope will be included in the stdlib, will have full
support for all the modes.

Please note that the conversions in "2)" above can be avoided in some
(most?) cases if PEP 3118 is accepted, because it will become possible
to expose and discover the "native" memory arrangement of an image
without accessing its buffer property (that, in my vision, will always
offer the "standard" arrangement defined in the PEP, to simplify
things for libraries that prefer a simpler interface, even if it may
be slightly less efficient in some, hopefully rare, cases).

-- 
Lino Mastrodomenico
E-mail: l.mastrodomenico at gmail.com


More information about the Python-3000 mailing list