[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Surfarray.array_alpha() bugfix, py2exe/py2app segfault



So it was that simple! It worked on the command line because it could load the library on demand. It failed when bundled because it was stripped to save space (or never copied in the first place). Dist tools didn't know to include it because it doesn't search deeply enough. For the mailing list archives, the solution is simple (though it may be obvious in the future, since we'll get a real exception):

from pygame import bufferproxy

I ran into a similar problem with sound files failing to load because I handed pygame an incorrect path, only it wasn't reported as an exception because it figured the path was raw PCM data. So I got no exception and a popping sound when trying to play the sound. Apparently it would take a bit of a redesign to fix that, but I figured I'd mention it.

Thanks so much. I'm explicitly including bufferproxy now and everything seems to be alright. I'm so glad I can bundle up my game again.

-Zack

On Feb 3, 2009, at 10:07 PM, Lenard Lindstrom wrote:

Hi everyone,

The answer is below the fold...


Lenard Lindstrom wrote:

Zack Schilling wrote:


In Pygame 1.8.1 and the latest 1.9.0 unstable, I've been having trouble using the surfarray module's pixels_alpha() and array_alpha() functions. I'm using 32bpp images with per-pixel alpha and I'm trying to work with the alpha data in numpy.

At first I couldn't get surfarray.array_alpha() to return a proper array (it returned all opaque values, surfarray.pixels_alpha() worked fine).

[snip]


So I went to find out why array_alpha wasn't working properly. I investigated in the pygame source and found the culprit in "pygame/ _numpysurfarray.py"

The following code, intended to catch 8 bit images or images without alpha values, was erroneously catching my perpixel images.

   if surface.get_bytesize () == 1 or not surface.get_alpha ():
       # 1 bpp surfaces and surfaces without alpha are always fully
       # opaque.

The problem was that per-pixel surfaces normally have the blacket alpha, returned by get_alpha(), set as 255, a True value. Surfaces returned by convert_alpha() have blanket alpha 0, a False value. This 0 value caused the failure.

The fix is simple, make sure that the image is less than 32bpp AND missing an alpha channel before giving up on it.

if surface.get_bytesize () == 1 or (not surface.get_alpha () and surface.get_bytesize () < 4):
       # 1 bpp surfaces and surfaces without alpha are always fully
       # opaque.

A pygame developer should make and commit that change.
Fixed in SVN rev. 1903. As long as the blanket alpha is not None, its value shouldn't matter for a per-pixel alpha surface as it is ignored. But a surface with a blanket alpha set to None is totally opaque, any per-pixel alpha values are ignored. Also 2 byte surfaces can have per-pixel alpha. So all there factors had to be considered when patching _numpysurfarray.py.

Once I fixed that issue, everything worked as expected... as long as I ran the script from the command line. Now if I used either array_alpha() or pixels_alpha() in a py2exe/p2app program, I got a segmentation fault! ( just like before the change with pixels_alpha() )

This is next on the agenda.

Simple. The bufferproxy module is not included in the executables. I would also check for surflock.

The moral of the story, when critical modules are missing, they should not be quietly ignored. An exception has to be raised. Brian Fisher did this with _numericsurfarray when Numeric is missing. It simply fails to import. I did the same for _numericsndarray. Now it needs to be done for Pygame extention modules that rely on other Pygame modules.

Lenard

--
Lenard Lindstrom
<len-l@xxxxxxxxx>