Commits

Anonymous committed 61a09a2

_Really_ fixed 24bpp access for pygame.surfarray.pixels3d().

Comments (0)

Files changed (3)

lib/_numpysurfarray.py

     bpp = surface.get_bytesize ()
     if bpp < 3 or bpp > 4:
         raise ValueError, "unsupported bit depth for 3D reference array"
+    lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN
 
     start = 0
     step = 0
-    end = 0
 
     # Check for RGB or BGR surface.
     shifts = surface.get_shifts ()
     if shifts[0] == 16 and shifts[1] == 8 and shifts[2] == 0:
         # RGB 
-        end = None
-        if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
+        if lilendian:
             start = 2
             step = -1
         else:
             start = 0
             step = 1
-    else:
+    elif shifts[2] == 16 and shifts[1] == 8 and shifts[0] == 0:
         # BGR
-        end = 3
-        if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
+        if lilendian:
             start = 0
             step = 1
         else:
             start = 2
             step = -1
+    else:
+        raise ValueError, "unsupported colormasks for 3D reference array"
 
-    array = numpy.frombuffer (surface.get_buffer (), numpy.uint8)
-    array.shape = surface.get_height (), surface.get_pitch ()
-    array = array[:,:surface.get_width () * bpp]
-    array = numpy.reshape (array, (surface.get_width (), surface.get_height (),
-                                   bpp))
-    array = array[:,:,start:end:step]
+    if bpp == 4 and not lilendian:
+        start += 1
+
+    array = numpy.ndarray \
+            (shape=(surface.get_width (), surface.get_height (), 3),
+             dtype=numpy.uint8, buffer=surface.get_buffer (),
+             offset=start, strides=(bpp, surface.get_pitch (),step))
     return array
 
 def array_alpha (surface):
     """
     if surface.get_bytesize () != 4:
         raise ValueError, "unsupported bit depth for alpha reference array"
+    lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN
 
     # ARGB surface.
     start = 0
     
-    if surface.get_shifts ()[3] == 24:
+    if surface.get_shifts ()[3] == 24 and lilendian:
         # RGBA surface.
         start = 3
+    elif surface.get_shifts ()[3] == 0 and not lilendian:
+        start = 3
+    else:
+        raise ValueError, "unsupported colormasks for alpha reference array"
 
-    width, height = surface.get_width (), surface.get_height ()
-    array = numpy.frombuffer (surface.get_buffer (), numpy.uint8)
-    array.shape = height, surface.get_pitch ()
-    array = array[:, start::4]
-    array = array[:, :width * 4]
-    return numpy.transpose (array)
+    array = numpy.ndarray \
+            (shape=(surface.get_width (), surface.get_height ()),
+             dtype=numpy.uint8, buffer=surface.get_buffer (),
+             offset=start, strides=(4, surface.get_pitch ()))
+    return array
 
 def array_colorkey (surface):
     """pygame.numpyarray.array_colorkey (Surface): return array
     0,                          /* tp_getattr */
     0,                          /* tp_setattr */
     0,                          /* tp_compare */
-    (reprfunc) _pxarray_repr,  /* tp_repr */
+    (reprfunc) _pxarray_repr,   /* tp_repr */
     0,                          /* tp_as_number */
-    &_pxarray_sequence,          /* tp_as_sequence */
-    &_pxarray_mapping,           /* tp_as_mapping */
+    &_pxarray_sequence,         /* tp_as_sequence */
+    &_pxarray_mapping,          /* tp_as_mapping */
     0,                          /* tp_hash */
     0,                          /* tp_call */
     0,                          /* tp_str */
-    PyObject_GenericGetAttr,    /* tp_getattro */
+    0,                          /* tp_getattro */
     0,                          /* tp_setattro */
     0,                          /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,
     if (surface->format->BytesPerPixel < 1  ||
         surface->format->BytesPerPixel > 4)
         return RAISE (PyExc_ValueError,
-            "unsupport bit depth for reference array");
+            "unsupported bit depth for reference array");
 
     return (PyObject *) _pxarray_new_internal
         (&PyPixelArray_Type, surfobj, 0, 0,
     module = Py_InitModule3 ("pixelarray", NULL, NULL);
     Py_INCREF (&PyPixelArray_Type);
     PyModule_AddObject (module, "PixelArray", (PyObject *) &PyPixelArray_Type);
-
+    PyPixelArray_Type.tp_getattro = PyObject_GenericGetAttr;
     dict = PyModule_GetDict (module);
 
     c_api[0] = &PyPixelArray_Type;

src/pixelarray_methods.c

     if (PyInt_Check (val))
     {
         long intval = PyInt_AsLong (val);
-        if ((intval < INT_MIN) || (intval > INT_MAX))
+        if (intval == -1 && PyErr_Occurred ())
         {
-            if (!PyErr_Occurred ())
-                PyErr_SetString (PyExc_ValueError, "invalid color argument");
+            PyErr_SetString (PyExc_ValueError, "invalid color argument");
             return 0;
         }
         *color = (Uint32) intval;
     }
     else if (PyLong_Check (val))
     {
-        long long longval = PyLong_AsLong (val);
-        if ((longval < INT_MIN) || (longval > INT_MAX))
+        unsigned long longval = PyLong_AsUnsignedLong (val);
+        if (PyErr_Occurred ())
         {
             PyErr_SetString(PyExc_ValueError, "invalid color argument");
             return 0;