From 54f96a6855a21bc7168bff82805ede34ae2ff1bb Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Tue, 1 Aug 2017 23:29:03 +0900 Subject: [PATCH] WebP wallpaper support (when libwebp is installed) --- userspace/py/bin/panel.py | 4 +++ userspace/py/bin/select_wallpaper.py | 11 ++++++- userspace/py/lib/toaru_webp.py | 45 ++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 userspace/py/lib/toaru_webp.py diff --git a/userspace/py/bin/panel.py b/userspace/py/bin/panel.py index 9738c05a1..16dbb4307 100755 --- a/userspace/py/bin/panel.py +++ b/userspace/py/bin/panel.py @@ -26,6 +26,7 @@ import text_region import toaru_fonts import fswait +import toaru_webp from menu_bar import MenuEntryAction, MenuEntrySubmenu, MenuEntryDivider, MenuWindow from icon_cache import get_icon @@ -1070,6 +1071,9 @@ def load_wallpaper(self, path=None): c = configparser.ConfigParser() c.read_string(conf_str) path = c['desktop'].get('wallpaper',self.fallback) + + if path.endswith('.webp') and toaru_webp.exists(): + return toaru_webp.load_webp(path) return cairo.ImageSurface.create_from_png(path) def finish_resize(self, msg): diff --git a/userspace/py/bin/select_wallpaper.py b/userspace/py/bin/select_wallpaper.py index 09b93e669..c74e13f6e 100755 --- a/userspace/py/bin/select_wallpaper.py +++ b/userspace/py/bin/select_wallpaper.py @@ -12,6 +12,7 @@ import yutani import text_region import toaru_fonts +import toaru_webp from button import Button import yutani_mainloop @@ -118,7 +119,10 @@ def load_directory(self, path): if not os.path.exists(path): return [] - return [os.path.join(path,x) for x in os.listdir(path) if x.endswith('.png')] + if toaru_webp.exists(): + return [os.path.join(path,x) for x in os.listdir(path) if x.endswith('.png') or x.endswith('.webp')] + else: + return [os.path.join(path,x) for x in os.listdir(path) if x.endswith('.png')] def find_wallpapers(self): self.wallpapers = [] @@ -139,8 +143,13 @@ def read_wallpaper(self): self.path = c['desktop'].get('wallpaper',self.fallback) def load_wallpaper(self): + if self.path.endswith('.webp') and toaru_webp.exists(): + self.wallpaper = toaru_webp.load_webp(self.path) + return + self.wallpaper = cairo.ImageSurface.create_from_png(self.path) + def draw(self): surface = self.get_cairo_surface() diff --git a/userspace/py/lib/toaru_webp.py b/userspace/py/lib/toaru_webp.py new file mode 100644 index 000000000..9ae5e984d --- /dev/null +++ b/userspace/py/lib/toaru_webp.py @@ -0,0 +1,45 @@ +""" +Small WebP library +""" +import os +import cairo +import ctypes + +_webp_lib = None + +WebPGetInfo = None +WebPDecodeBGRAInto = None + +def exists(): + return os.path.exists('/usr/lib/libwebp.so') + +def load_webp(path): + global _webp_lib + global WebPGetInfo + global WebPDecodeBGRAInto + + if not exists(): + return None + + if not _webp_lib: + _webp_lib = ctypes.CDLL('libwebp.so') + WebPGetInfo = _webp_lib.WebPGetInfo + WebPGetInfo.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)] + WebPGetInfo.restype = ctypes.c_int + + WebPDecodeBGRAInto = _webp_lib.WebPDecodeBGRAInto + WebPDecodeBGRAInto.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.POINTER(ctypes.c_char), ctypes.c_int, ctypes.c_int] + WebPDecodeBGRAInto.restype = ctypes.c_int + + with open(path, 'rb') as f: + data = f.read() + + _width = ctypes.c_int() + _height = ctypes.c_int() + WebPGetInfo(data, len(data), ctypes.byref(_width), ctypes.byref(_height)) + width, height = _width.value, _height.value + + buf = ctypes.create_string_buffer(b'\000' * width * height * 4) + WebPDecodeBGRAInto(data, len(data), buf, width * height * 4, width * 4) + + return cairo.ImageSurface.create_for_data(buf, cairo.FORMAT_ARGB32, width, height, width * 4)