Commits

Lenard Lindstrom committed a1c860d

Bug fix: Surface.blit seqfaulted on Debian for 8 bit target and 32 source with per-pixel alpha when the display was not initialized; add special blit case.

Comments (0)

Files changed (2)

     if (src->format->BytesPerPixel == 1) {
         result = pygame_Blit (src, srcrect, dst, dstrect, 0);
     }
-    else {
+    else if (SDL_WasInit (SDL_INIT_VIDEO)) {
         src = SDL_DisplayFormat (src);
         if (src) {
         result = SDL_BlitSurface (src, srcrect, dst, dstrect);
         result = -1;
         }
     }
+    else {
+        SDL_PixelFormat *fmt = src->format;
+        SDL_PixelFormat newfmt;
+
+        newfmt.palette = 0;  /* Set NULL (or SDL gets confused) */
+        newfmt.BitsPerPixel = fmt->BitsPerPixel;
+        newfmt.BytesPerPixel = fmt->BytesPerPixel;
+        newfmt.Amask = 0;
+        newfmt.Rmask = fmt->Rmask;
+        newfmt.Gmask = fmt->Gmask;
+        newfmt.Bmask = fmt->Bmask;
+        newfmt.Ashift = 0;
+        newfmt.Rshift = fmt->Rshift;
+        newfmt.Gshift = fmt->Gshift;
+        newfmt.Bshift = fmt->Bshift;
+        newfmt.Aloss = 0;
+        newfmt.Rloss = fmt->Rloss;
+        newfmt.Gloss = fmt->Gloss;
+        newfmt.Bloss = fmt->Bloss;
+        newfmt.colorkey = 0;
+        newfmt.alpha = 0;
+        src = SDL_ConvertSurface (src, &newfmt, SDL_SWSURFACE);
+        if (src) {
+            result = SDL_BlitSurface (src, srcrect, dst, dstrect);
+            SDL_FreeSurface (src);
+        }
+        else {
+            result = -1;
+        }
+    }
     /* Py_END_ALLOW_THREADS */
     }
     else {

test/surface_test.py

 
         self.assertEquals(s.get_at((0,0)), (32,32,32,31))
 
+    def test_blit__SRCALPHA32_to_8(self):
+        # Bug: fatal
+        # SDL_DisplayConvert segfaults when video is uninitialized.
+        target = pygame.Surface((11, 8), 0, 8)
+        color = target.get_palette_at(2)
+        source = pygame.Surface((1, 1), pygame.SRCALPHA, 32)
+        source.set_at((0, 0), color)
+        target.blit(source, (0, 0))
+
     def todo_test_convert(self):
 
         # __doc__ (as of 2008-08-02) for pygame.surface.Surface.convert: