# Commits

committed 2799158

upgrade numpy handling to Python 3.x

• Participants
• Parent commits 9a99a51
• Branches default

# File examples/arraydemo.py

if surfarray.get_arraytype() == 'numpy':
import numpy as N
-        from numpy import int32
+        from numpy import int32, uint8, uint
else:
import Numeric as N
-        from Numeric import Int32 as int32
+        from Numeric import Int32 as int32, UInt8 as uint8, UInt as uint

pygame.init()
print ('Using %s' % surfarray.get_arraytype().capitalize())

#soften
-    soften = N.array(rgbarray)*1
-    soften[1:,:]  += rgbarray[:-1,:]*8
-    soften[:-1,:] += rgbarray[1:,:]*8
-    soften[:,1:]  += rgbarray[:,:-1]*8
-    soften[:,:-1] += rgbarray[:,1:]*8
-    soften /= 33
+    #having factor as an array forces integer upgrade during multiplication
+    #of rgbarray, even for numpy.
+    factor = N.array((8,), int32)
+    soften = N.array(rgbarray, int32)
+    soften[1:,:]  += rgbarray[:-1,:] * factor
+    soften[:-1,:] += rgbarray[1:,:] * factor
+    soften[:,1:]  += rgbarray[:,:-1] * factor
+    soften[:,:-1] += rgbarray[:,1:] * factor
+    soften //= 33
surfdemo_show(soften, 'soften')

dest = N.zeros(rgbarray.shape)
dest[:] = 20, 50, 100
diff = (dest - src) * 0.50
-    if surfarray.get_arraytype() == 'numpy':
-        xfade = src + diff.astype(N.uint)
-    else:
-        xfade = src + diff.astype(N.Int)
+    xfade = src + diff.astype(uint)

# File lib/_numpysurfarray.py

"""

import pygame
+from pygame.compat import bytes_
+from pygame._arraysurfarray import blit_array
import numpy
-import re
+

def array2d (surface):
"""pygame.numpyarray.array2d (Surface): return array
if bpp <= 0 or bpp > 4:
raise ValueError("unsupported bit depth for 2D array")

+    size = surface.get_size ()
+    width, height = size
+
# Taken from Alex Holkner's pygame-ctypes package. Thanks a lot.
-    data = surface.get_buffer ().raw
-
-    # Remove extra pitch from each row.
-    width = surface.get_width ()
-    pitchdiff = surface.get_pitch () - width * bpp
-    if pitchdiff > 0:
-        pattern = re.compile ('(%s)%s' % ('.' * width * bpp, '.' * pitchdiff),
-                              flags=re.DOTALL)
-        data = ''.join (pattern.findall (data))
+    data = numpy.frombuffer (surface.get_buffer (), numpy.uint8)
+    pitch = surface.get_pitch ()
+    row_size = width * bpp
+    if pitch != row_size:
+        data.shape = (height, pitch)
+        data = data[:, 0:row_size]

+    dtype = (None, numpy.uint8, numpy.uint16, numpy.int32, numpy.int32)[bpp]
+    array = numpy.zeros (size, dtype, 'F')
+    array_data = numpy.frombuffer (array, numpy.uint8)
if bpp == 3:
-        # Pad each triplet of bytes with another zero
-        pattern = re.compile ('...', flags=re.DOTALL)
-        data = '\0'.join (pattern.findall (data))
-        if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
-            data += '\0'
-        else:
-            data = '\0' + data
-        bpp = 4
-
-    typecode = (numpy.uint8, numpy.uint16, None, numpy.int32)[bpp - 1]
-    array = numpy.fromstring (data, typecode)
-    array.shape = (surface.get_height (), width)
-    array = numpy.transpose (array)
+        data.shape = (height, width, 3)
+        array_data.shape = (height, width, 4)
+        array_data[:,:,:3] = data[...]
+    else:
+        data.shape = (height, row_size)
+        array_data.shape = (height, row_size)
+        array_data[...] =  data[...]
return array

-
def pixels2d (surface):
"""pygame.numpyarray.pixels2d (Surface): return array

surface = pygame.Surface ((shape[0], shape[1]), 0, bpp, (r, g, b, 0))
blit_array (surface, array)
return surface
-
-def blit_array (surface, array):
-    """pygame.numpyarray.blit_array (Surface, array): return None
-
-    blit directly from a array values
-
-    Directly copy values from an array into a Surface. This is faster
-    than converting the array into a Surface and blitting. The array
-    must be the same dimensions as the Surface and will completely
-    replace all pixel values.
-
-    This function will temporarily lock the Surface as the new values
-    are copied.
-    """
-    bpp = surface.get_bytesize ()
-    if bpp <= 0 or bpp > 4:
-        raise ValueError("unsupported bit depth for surface")
-
-    shape = array.shape
-    width = surface.get_width ()
-
-    typecode = (numpy.uint8, numpy.uint16, None, numpy.uint32)[bpp - 1]
-    array = array.astype (typecode)
-
-    # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
-    # lot.
-    if len(shape) == 3 and shape[2] == 3:
-        array = numpy.transpose (array, (1, 0, 2))
-        shifts = surface.get_shifts ()
-        losses = surface.get_losses ()
-        array = (array[:,:,::3] >> losses[0] << shifts[0]) | \
-                (array[:,:,1::3] >> losses[1] << shifts[1]) | \
-                (array[:,:,2::3] >> losses[2] << shifts[2])
-    elif len (shape) == 2:
-        array = numpy.transpose (array)
-    else:
-        raise ValueError("must be a valid 2d or 3d array")
-
-    if width != shape[0] or surface.get_height () != shape[1]:
-        raise ValueError("array must match the surface dimensions")
-
-    itemsize = array.itemsize
-    data = array.tostring ()
-
-    if itemsize > bpp:
-        # Trim bytes from each element, keep least significant byte(s)
-        pattern = '%s(%s)' % ('.' * (itemsize - bpp), '.' * bpp)
-        if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
-            pattern = '(%s)%s' % ('.' * bpp, '.' * (itemsize - bpp))
-        data = ''.join (re.compile (pattern, flags=re.DOTALL).findall (data))
-    elif itemsize < bpp:
-        # Add pad bytes to each element, at most significant end
-        pad = '\0' * (bpp - itemsize)
-        pixels = re.compile ('.' * itemsize, flags=re.DOTALL).findall (data)
-        if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
-            data = data + pad
-        else:
-            data = pad + data
-
-    pitchdiff = surface.get_pitch () - width * bpp
-    if pitchdiff > 0:
-        pad = '\0' * pitchdiff
-        rows = re.compile ('.' * width * bpp, flags=re.DOTALL).findall (data)
-
-    surface.get_buffer ().write (data, 0)

def map_array (surface, array):
"""pygame.numpyarray.map_array (Surface, array3d): return array2d

# File lib/surfarray.py

if not __hasnumpy and not __hasnumeric:
raise ImportError("no module named numpy or Numeric found")

-from _arraysurfarray import blit_array
+from pygame._arraysurfarray import blit_array

def array2d (surface):
"""pygame.surfarray.array2d (Surface): return array
return numpysf.make_surface (array)
raise NotImplementedError("surface arrays are not supported")

-##def blit_array (surface, array):
-##    """pygame.surfarray.blit_array (Surface, array): return None
-##
-##    Blit directly from a array values.
-##
-##    Directly copy values from an array into a Surface. This is faster
-##    than converting the array into a Surface and blitting. The array
-##    must be the same dimensions as the Surface and will completely
-##    replace all pixel values.
-##
-##    This function will temporarily lock the Surface as the new values
-##    are copied.
-##    """
-##    if __arraytype == "numeric":
-##        return numericsf.blit_array (surface, array)
-##    elif __arraytype == "numpy":
-##        return numpysf.blit_array (surface, array)
-##    raise NotImplementedError("surface arrays are not supported")
-
def map_array (surface, array):
"""pygame.surfarray.map_array (Surface, array3d): return array2d

# File src/_arraysurfarray.c

static int
_get_array_interface(PyObject *obj,
-		     PyObject **cobj_p,
-		     PyArrayInterface **inter_p)
+                     PyObject **cobj_p,
+                     PyArrayInterface **inter_p)
{
-    if (!(*cobj_p = PyObject_GetAttrString(obj, "__array_struct__"))) {
-	if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-		PyErr_Clear();
-		PyErr_SetString(PyExc_ValueError,
-				"no C-struct array interface");
-	    }
-	return 0;
+    PyObject *cobj = PyObject_GetAttrString(obj, "__array_struct__");
+    PyArrayInterface *inter = NULL;
+
+    if (cobj == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                PyErr_Clear();
+                PyErr_SetString(PyExc_ValueError,
+                                "no C-struct array interface");
+        }
+        return 0;
}

-    if (!PyCObject_Check(*cobj_p) ||  /* conditional 'or's */
-	!(*inter_p = PyCObject_AsVoidPtr(*cobj_p)) ||
-	(*inter_p)->two != 2) {
-	Py_DECREF(*cobj_p);
-	PyErr_SetString(PyExc_ValueError, "invalid array interface");
-	return 0;
+#if defined(PyCObject_Check)
+    if (PyCObject_Check(cobj)) {
+        inter = (PyArrayInterface *)PyCObject_AsVoidPtr(cobj);
}
+#endif
+#if defined(PyCapsule_CheckExact)
+    if (PyCapsule_IsValid(cobj, NULL)) {
+        inter = (PyArrayInterface *)PyCapsule_GetPointer(cobj, NULL);
+    }
+#endif
+    if (inter == NULL ||   /* conditional or */
+        inter->two != 2  ) {
+        Py_DECREF(cobj);
+        PyErr_SetString(PyExc_ValueError, "invalid array interface");
+        return 0;
+    }
+
+    *cobj_p = cobj;
+    *inter_p = inter;
return 1;
}

/*macros used to blit arrays*/
-#define COPYMACRO_2D(DST, SRC)                                           \
-    for (loopy = 0; loopy < sizey; ++loopy)                              \
-    {                                                                    \
-        DST* imgrow = (DST*)(((char*)surf->pixels)+loopy*surf->pitch);   \
-        Uint8* datarow = (Uint8*)array_data + stridey * loopy;           \
-        for (loopx = 0; loopx < sizex; ++loopx)                          \
-            *(imgrow + loopx) = (DST)*(SRC*)(datarow + stridex * loopx); \
+#define COPYMACRO_2D(DST, SRC)                                            \
+    for (loopy = 0; loopy < sizey; ++loopy)                               \
+    {                                                                     \
+        DST* imgrow = (DST*)(((char*)surf->pixels)+loopy*surf->pitch);    \
+        Uint8* datarow = (Uint8*)array_data + stridey * loopy;            \
+        for (loopx = 0; loopx < sizex; ++loopx)                           \
+            *(imgrow + loopx) = (DST)*(SRC*)(datarow + stridex * loopx);  \
}

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
-#define COPYMACRO_2D_24_PIXEL(pix, data, SRC)    			\
-    *pix++ = *data;					                \
-    *pix++ = *(data + 1);					        \
+#define COPYMACRO_2D_24_PIXEL(pix, data, SRC)                             \
+    *pix++ = *data;                                                       \
+    *pix++ = *(data + 1);                                                 \
*pix++ = *(data + 2);
#else
-#define COPYMACRO_2D_24_PIXEL(pix, data, SRC)    			\
-    *pix++ = *(data + sizeof (SRC) - 1);				\
-    *pix++ = *(data + sizeof (SRC) - 2);				\
+#define COPYMACRO_2D_24_PIXEL(pix, data, SRC)                             \
+    *pix++ = *(data + sizeof (SRC) - 1);                                  \
+    *pix++ = *(data + sizeof (SRC) - 2);                                  \
*pix++ = *(data + sizeof (SRC) - 3);
#endif

-#define COPYMACRO_2D_24(SRC)                                            \
-    for (loopy = 0; loopy < sizey; ++loopy)                             \
-    {                                                                   \
-        Uint8 *pix = ((Uint8 *)surf->pixels) + loopy * surf->pitch;     \
-        Uint8 *data = (Uint8 *)array_data + stridey * loopy;            \
-        Uint8 *end = pix + 3 * sizex;                                   \
-        while (pix != end) {                                            \
-            COPYMACRO_2D_24_PIXEL(pix, data, SRC)			\
-            data += stridex;                                            \
-        }                                                               \
+#define COPYMACRO_2D_24(SRC)                                              \
+    for (loopy = 0; loopy < sizey; ++loopy)                               \
+    {                                                                     \
+        Uint8 *pix = ((Uint8 *)surf->pixels) + loopy * surf->pitch;       \
+        Uint8 *data = (Uint8 *)array_data + stridey * loopy;              \
+        Uint8 *end = pix + 3 * sizex;                                     \
+        while (pix != end) {                                              \
+            COPYMACRO_2D_24_PIXEL(pix, data, SRC)                         \
+            data += stridex;                                              \
+        }                                                                 \
}

#define COPYMACRO_3D(DST, SRC)                                            \
{                                                                   \
Uint8 *pix = ((Uint8*)surf->pixels) + surf->pitch * loopy;      \
Uint8 *data = (Uint8*)array_data + stridey * loopy;             \
-	Uint8 *end = pix + 3 * sizex;                                   \
+        Uint8 *end = pix + 3 * sizex;                                   \
while (pix != end) {                                            \
*pix++ = (Uint8)*(SRC*)(data + stridez_0);                  \
*pix++ = (Uint8)*(SRC*)(data + stridez_1);                  \
}

static PyObject*
-blit_array(PyObject* self, PyObject* arg)
+blit_array(PyObject *self, PyObject *arg)
{
PyObject *surfobj, *arrayobj;
PyObject *cobj;

switch (inter->typekind) {
case 'i':  /* integer */
-	break;
+        break;
case 'u':  /* unsigned integer */
-	break;
+        break;
case 'S':  /* fixed length character field */
-	break;
+        break;
case 'V':  /* structured element: record */
-	break;
+        break;
default:
-	Py_DECREF(cobj);
-	PyErr_Format(PyExc_ValueError, "unsupported array type '%c'",
-		     inter->typekind);
-	return NULL;
+        Py_DECREF(cobj);
+        PyErr_Format(PyExc_ValueError, "unsupported array type '%c'",
+                     inter->typekind);
+        return NULL;
}

if (!(inter->nd == 2 || (inter->nd == 3 && inter->shape[2] == 3)))
Py_DECREF(cobj);
return RAISE(PyExc_ValueError, "array must match surface dimensions");
}
-    if (!PySurface_LockBy(surfobj, (PyObject *) arrayobj)) {
+    if (!PySurface_LockBy(surfobj, arrayobj)) {
Py_DECREF(cobj);
return NULL;
}
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
}
else {
Py_DECREF(cobj);
-            if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+            if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
}
}
else {
-	    Uint16 alpha = 0;
-		alpha = 255 >> format->Aloss << format->Ashift;
-	    }
+            Uint16 alpha = 0;
+                alpha = 255 >> format->Aloss << format->Ashift;
+            }
switch (inter->itemsize) {
case sizeof (Uint8):
COPYMACRO_3D(Uint16, Uint8);
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
case 3:
/* Assumption: The rgb components of a 24 bit pixel are in
separate bytes.
-	*/
+        */
if (inter->nd == 2) {
switch (inter->itemsize) {
case sizeof (Uint32):
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
}
else {
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
-	    size_t stridez_0 = (Rshift ==  0 ? 0        :
-				Gshift ==  0 ? stridez  :
-				               stridez2   );
-	    size_t stridez_1 = (Rshift ==  8 ? 0        :
-				Gshift ==  8 ? stridez  :
+            size_t stridez_0 = (Rshift ==  0 ? 0        :
+                                Gshift ==  0 ? stridez  :
stridez2   );
-	    size_t stridez_2 = (Rshift == 16 ? 0        :
+            size_t stridez_1 = (Rshift ==  8 ? 0        :
+                                Gshift ==  8 ? stridez  :
+                                               stridez2   );
+            size_t stridez_2 = (Rshift == 16 ? 0        :
Gshift == 16 ? stridez  :
-				               stridez2   );
+                                               stridez2   );
#else
-	    size_t stridez_2 = (Rshift ==  0 ? 0        :
-				Gshift ==  0 ? stridez  :
-				               stridez2   );
-	    size_t stridez_1 = (Rshift ==  8 ? 0        :
-				Gshift ==  8 ? stridez  :
+            size_t stridez_2 = (Rshift ==  0 ? 0        :
+                                Gshift ==  0 ? stridez  :
stridez2   );
-	    size_t stridez_0 = (Rshift == 16 ? 0        :
+            size_t stridez_1 = (Rshift ==  8 ? 0        :
+                                Gshift ==  8 ? stridez  :
+                                               stridez2   );
+            size_t stridez_0 = (Rshift == 16 ? 0        :
Gshift == 16 ? stridez  :
-				               stridez2   );
+                                               stridez2   );
#endif
switch (inter->itemsize) {
case sizeof (Uint8):
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
}
}
else {
-	    Uint32 alpha = 0;
-		alpha = 255 >> format->Aloss << format->Ashift;
-	    }
+            Uint32 alpha = 0;
+                alpha = 255 >> format->Aloss << format->Ashift;
+            }
switch (inter->itemsize) {
case sizeof (Uint8):
COPYMACRO_3D(Uint32, Uint8);
break;
default:
Py_DECREF(cobj);
-                if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+                if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_ValueError,
break;
default:
Py_DECREF(cobj);
-        if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+        if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
return RAISE(PyExc_RuntimeError, "unsupported bit depth for image");
}

Py_DECREF(cobj);
-    if (!PySurface_UnlockBy(surfobj, (PyObject *) arrayobj)) {
+    if (!PySurface_UnlockBy(surfobj, arrayobj)) {
return NULL;
}
Py_RETURN_NONE;
*/
import_pygame_base();
if (PyErr_Occurred ()) {
-	MODINIT_ERROR;
+        MODINIT_ERROR;
}
import_pygame_surface();
if (PyErr_Occurred ()) {
-	MODINIT_ERROR;
+        MODINIT_ERROR;
}

#if PY3

# File test/sndarray_test.py

else:
from test.test_utils import test_not_implemented, unittest
import pygame
+from pygame.compat import as_bytes

arraytype = ""
try:
if not arraytype:
self.fail("no array package installed")

+        null_byte = as_bytes('\x00')
def check_sample(size, channels, test_data):
try:
pygame.mixer.init(22050, size, channels)
try:
__, sz, __ = pygame.mixer.get_init()
if sz == size:
-                    zeroed = '\0' * ((abs(size) // 8) *
-                                     len(test_data) *
-                                     channels)
-                    snd = pygame.mixer.Sound(buffer(zeroed))
+                    zeroed = null_byte * ((abs(size) // 8) *
+                                          len(test_data) *
+                                          channels)
+                    snd = pygame.mixer.Sound(buffer=zeroed)
samples = pygame.sndarray.samples(snd)
self._assert_compatible(samples, size)
-                    print ('X %s' % (samples.shape,))
-                    print ('Y %s' % (test_data,))
+                    ##print ('X %s' % (samples.shape,))
+                    ##print ('Y %s' % (test_data,))
samples[...] = test_data
arr = pygame.sndarray.array(snd)
self.failUnless(alltrue(samples == arr),