Commits

Lenard Lindstrom  committed b51cd33

Big-endian fixes for pygame.Surface

The surface_test.py unit tests now pass on a PowerPC.

  • Participants
  • Parent commits c86a02a

Comments (0)

Files changed (2)

File src/surface.c

     SDL_PixelFormat *format = surf->format;
     Uint8 *pixels = (Uint8 *) surf->pixels;
     int x, y;
-    Sint32 color;
+    Uint32 color;
     Uint8 *pix;
 
     if (!PyArg_ParseTuple (args, "(ii)", &x, &y))
 {
     SDL_Surface *surf = PySurface_AsSurface (self);
     /* Need to use 64bit vars so this works on 64 bit pythons. */
-    Uint64 r, g, b, a;
+    unsigned long r, g, b, a;
 
     if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a))
         return NULL;
 surf_set_shifts (PyObject *self, PyObject *args)
 {
     SDL_Surface *surf = PySurface_AsSurface (self);
-    Uint64 r, g, b, a;
+    unsigned long r, g, b, a;
 
     if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a))
         return NULL;
     }
 
     pixels = (Uint8 *) surf->pixels;
+    if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+        pixels += format->BytesPerPixel - sizeof (Uint32);
+    }
 
     min_y = 0;
     min_x = 0;
             return _raise_get_view_ndim_error (format->BytesPerPixel * 8,
                                                view_kind);
         }
-        if ((format->Gmask << 8 != format->Rmask ||
-             format->Gmask >> 8 != format->Bmask    ) &&
-            (format->Gmask >> 8 != format->Rmask ||
-             format->Gmask << 8 != format->Bmask    )    ) {
+        if (format->Gmask != 0x00ff00 &&
+            (format->BytesPerPixel != 4 ||
+             format->Gmask != 0xff0000)) {
             return RAISE (PyExc_ValueError,
                           "unsupport colormasks for 3D reference array");
         }
     view_p->shape[2] = 3;
     view_p->strides[0] = pixelsize;
     view_p->strides[1] = surface->pitch;
-    if (surface->format->Rmask == 0x00ff0000U) {
+    switch (surface->format->Rmask) {
+
+    case 0xffU:
+        view_p->strides[2] = lilendian ? 1 : -1;
+        startpixel += lilendian ? 0 : pixelsize - 1;
+        break;
+    case 0xff00U:
+        assert(pixelsize == 4);
+        view_p->strides[2] = lilendian ? 1 : -1;
+        startpixel += lilendian ? 1 : pixelsize - 2;
+        break;
+    case 0xff0000U:
+        view_p->strides[2] = lilendian ?  -1 : 1;
+        startpixel += lilendian ? 3 : pixelsize - 3;
+        break;
+    default: /* 0xff000000U */
+        assert(pixelsize == 4);
         view_p->strides[2] = lilendian ? -1 : 1;
-        startpixel += lilendian ? 2 : pixelsize - 3;
-    }
-    else {
-        view_p->strides[2] = lilendian ? 1 : -1;
-        startpixel += lilendian ? 0 : (pixelsize - 1);
+        startpixel += lilendian ? 3 : 0;
     }
     view_p->buf = startpixel;
     Py_INCREF (obj);
            the allowable masks for 24 bit and 32 bit surfaces */
 
     case 0x000000ffU:
-        startpixel += lilendian ? 0 : 3;
+        startpixel += lilendian ? 0 : pixelsize - 1;
         break;
     case 0x0000ff00U:
-        startpixel += lilendian ? 1 : 2;
+        startpixel += lilendian ? 1 : pixelsize - 2;
         break;
     case 0x00ff0000U:
-        startpixel += lilendian ? 2 : 1;
+        startpixel += lilendian ? 2 : pixelsize - 3;
         break;
     case 0xff000000U:
         startpixel += lilendian ? 3 : 0;

File test/surface_test.py

 
         # Check for RGB or BGR surface.
         if s_shifts[0:3] == [0, 8, 16]:
-            # RGB
             if self.lilendian:
+                # RGB
                 offset = 0
                 step = 1
             else:
+                # BGR
                 offset = s_bytesize - 1
                 step = -1
+        elif s_shifts[0:3] == [8, 16, 24]:
+            if self.lilendian:
+                # xRGB
+                offset = 1
+                step = 1
+            else:
+                # BGRx
+                offset = s_bytesize - 2
+                step = -1
         elif s_shifts[0:3] == [16, 8, 0]:
-            # BGR
             if self.lilendian:
+                # BGR
                 offset = 2
                 step = -1
             else:
-                offset = 1
+                # RGB
+                offset = s_bytesize - 3
                 step = 1
+        elif s_shifts[0:3] == [24, 16, 8]:
+            if self.lilendian:
+                # BGRx
+                offset = 2
+                step = -1
+            else:
+                # RGBx
+                offset = s_bytesize - 4
+                step = -1
         else:
             return
 
             masks = s_masks[2::-1] + s_masks[3:4]
             self._check_interface_3D(pygame.Surface(sz, 0, 24, masks))
 
+        masks = [0xff00, 0xff0000, 0xff000000, 0]
+        self._check_interface_3D(pygame.Surface(sz, 0, 32, masks))
+
         # Unsupported RGB byte orders
-        masks = [0xff00, 0xff0000, 0xff000000, 0]
-        self.assertRaises(ValueError,
-                          pygame.Surface(sz, 0, 32, masks).get_view, '3')
         masks = [0xff00, 0xff, 0xff0000, 0]
         self.assertRaises(ValueError,
                           pygame.Surface(sz, 0, 24, masks).get_view, '3')