Esempio n. 1
0
def save_png(surf, filename):
    alpha = bool(surf.format.Amask)
    if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
        rmask, gmask, bmask, amask = 0xff, 0xff00, 0xff0000, 0xff000000
    else:
        rmask, gmask, bmask, amask = 0xff00, 0xff0000, 0xff, 0x000000ff
    ss_surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SWSURFACE | sdl.SDL_SRCALPHA,
                                       surf.w, surf.h, 32 if alpha else 24,
                                       rmask, gmask, bmask, amask)
    if not ss_surf:
        return -1
    with opaque(surf):
        rect = ffi.new('SDL_Rect*')
        rect.w = surf.w
        rect.h = surf.h
        sdl.SDL_BlitSurface(surf, rect, ss_surf, ffi.NULL)

    ss_rows = ffi.new('unsigned char*[]', surf.h)
    ss_pixels = ffi.cast('unsigned char*', ss_surf.pixels)
    for i in range(surf.h):
        ss_rows[i] = ss_pixels + i * ss_surf.pitch
    err_msg = ffi.new('char**')
    result = pnglib.write_png(filename, ss_rows, surf.w, surf.h,
                              (pnglib.PNG_COLOR_TYPE_RGB_ALPHA if alpha else
                               pnglib.PNG_COLOR_TYPE_RGB), 8, err_msg)

    sdl.SDL_FreeSurface(ss_surf)
    if result == -1:
        raise IOError("PNGError: %s" % ffi.string(err_msg[0]))
    return result
Esempio n. 2
0
def save_jpg(surf, filename):
    if (surf.format.BytesPerPixel == 3 and not (surf.flags & sdl.SDL_SRCALPHA)
            and surf.format.Rshift == 0):
        ss_surf = surf
    else:
        if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
            rmask, gmask, bmask, amask = 0xff, 0xff00, 0xff0000, 0xff000000
        else:
            rmask, gmask, bmask, amask = 0xff00, 0xff, 0xff0000, 0xff000000
        ss_surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SWSURFACE, surf.w, surf.h,
                                           24, rmask, gmask, bmask, amask)
        if not ss_surf:
            return -1
        rect = ffi.new('SDL_Rect*')
        rect.w = surf.w
        rect.h = surf.h
        sdl.SDL_BlitSurface(surf, rect, ss_surf, ffi.NULL)

    ss_rows = ffi.new('unsigned char*[]', surf.h)
    ss_pixels = ffi.cast('unsigned char*', ss_surf.pixels)
    for i in range(surf.h):
        ss_rows[i] = ss_pixels + i * ss_surf.pitch
    err_msg = ffi.new('char**')
    result = jpglib.write_jpeg(filename, ss_rows, surf.w, surf.h, 85, err_msg)

    if ss_surf is not surf:
        sdl.SDL_FreeSurface(ss_surf)
    if result == -1:
        raise IOError("JPGError: %s" % ffi.string(err_msg[0]))
    return result
Esempio n. 3
0
 def __del__(self):
     if self._c_surface and (sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO) or not \
                             (self._c_surface.flags & sdl.SDL_HWSURFACE)):
         sdl.SDL_FreeSurface(self._c_surface)
     self._c_surface = None
     self._format = None
     self._w = None
     self._h = None
Esempio n. 4
0
    def blit(self, source, dest, area=None, special_flags=0):
        """ blit(source, dest, area=None, special_flags = 0) -> Rect
        draw one image onto another
        """
        if not self._c_surface or not source._c_surface:
            raise SDLError("display Surface quit")
        if self.is_pure_opengl():
            raise SDLError("Cannot blit to OPENGL Surfaces (OPENGLBLIT is ok)")

        srcrect = ffi.new('SDL_Rect*')
        destrect = ffi.new('SDL_Rect*')
        if area is not None:
            srcrect.x, srcrect.y, srcrect.w, srcrect.h = \
                    rect_vals_from_obj(area)
        else:
            srcrect.w = source._w
            srcrect.h = source._h
        if isinstance(dest, tuple) and len(dest) == 2:
            destrect.x = int(dest[0])
            destrect.y = int(dest[1])
            destrect.w = source._w
            destrect.h = source._h
        else:
            destrect.x, destrect.y, destrect.w, destrect.h = \
                    rect_vals_from_obj(dest)

        c_dest = self._c_surface
        c_src = source._c_surface
        c_subsurface = None
        flags = special_flags

        if self.subsurfacedata:
            owner = self.subsurfacedata.owner
            c_subsurface = owner._c_surface
            suboffsetx = self.subsurfacedata.xoffset
            suboffsety = self.subsurfacedata.yoffset
            while owner.subsurfacedata:
                subdata = owner.subsurfacedata
                owner = subdata.owner
                c_subsurface = owner._c_surface
                suboffsetx += subdata.xoffset
                suboffsety += subdata.yoffset

            orig_clip = ffi.new('SDL_Rect*')
            sub_clip = ffi.new('SDL_Rect*')
            sdl.SDL_GetClipRect(c_subsurface, orig_clip)
            sdl.SDL_GetClipRect(self._c_surface, sub_clip)
            sub_clip[0].x += suboffsetx
            sub_clip[0].y += suboffsety
            sdl.SDL_SetClipRect(c_subsurface, sub_clip)
            destrect.x += suboffsetx
            destrect.y += suboffsety
            c_dest = c_subsurface

        # TODO: implement special blend flags
        # these checks come straight from pygame - copied comments
        if (c_dest.format.Amask and (c_dest.flags & sdl.SDL_SRCALPHA)
                and not (c_src.format.Amask
                         and not (c_src.flags & sdl.SDL_SRCALPHA))
                and (c_dest.format.BytesPerPixel == 2
                     or c_dest.format.BytesPerPixel == 4)):
            # SDL works for 2 and 4 bytes
            res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, flags)
        elif flags or (c_src.flags & (sdl.SDL_SRCALPHA | sdl.SDL_SRCCOLORKEY)
                       and c_dest.pixels == c_src.pixels
                       and check_surface_overlap(c_src, srcrect, c_dest,
                                                 destrect)):
            '''
            This simplification is possible because a source subsurface
            is converted to its owner with a clip rect and a dst
            subsurface cannot be blitted to its owner because the
            owner is locked.
            '''
            res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, flags)
        # can't blit alpha to 8bit, crashes SDL
        elif (c_dest.format.BytesPerPixel == 1
              and (c_src.format.Amask or c_src.flags & sdl.SDL_SRCALPHA)):
            if c_src.format.BytesPerPixel == 1:
                res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, 0)
            elif sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO):
                # TODO: SDL_DisplayFormat segfaults
                c_src = sdl.SDL_DisplayFormat(c_src)
                if c_src:
                    res = sdl.SDL_BlitSurface(c_src, srcrect, c_dest, destrect)
                    sdl.SDL_FreeSurface(c_src)
                else:
                    res = -1
            else:
                raise NotImplementedError()
        else:
            res = sdl.SDL_BlitSurface(c_src, srcrect, c_dest, destrect)

        if c_subsurface:
            sdl.SDL_SetClipRect(c_subsurface, orig_clip)
            destrect.x -= suboffsetx
            destrect.y -= suboffsety
        else:
            # TODO: prep/unprep
            pass

        if res == -1:
            raise SDLError.from_sdl_error()
        elif res == -2:
            raise SDLError("Surface was lost")

        return Rect._from4(destrect.x, destrect.y, destrect.w, destrect.h)