1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

[IconLoader] add optional gif loader.

This commit is contained in:
Dave Davenport 2020-10-18 21:37:05 +02:00
parent d8a420c952
commit 5994df7f04
5 changed files with 115 additions and 3 deletions

View file

@ -168,6 +168,7 @@ rofi_LDADD=\
$(cairo_LIBS)\
$(librsvg_LIBS)\
$(libjpeg_LIBS)\
$(libgif_LIBS)\
$(LIBS)
##

View file

@ -165,7 +165,38 @@ dnl Gets the resource compile tool path.
dnl ---------------------------------------------------------------------
AM_PATH_GLIB_2_0
dnl Test for libgif or libungif
AC_ARG_WITH([libgif],
AS_HELP_STRING([--with-libgif=PREFIX],
[Prefix where libgif is installed, or 'no' to disable]),
[libgif_prefix="$withval"], [libgif_prefix="${prefix}"])
if test x$with_libgif != xno && test -z "$libgif_LIBS"; then
GIF_CFLAGS="-I${libgif_prefix}/include"
GIF_LIBS="-L${libgif_prefix}/lib"
save_cflags=$CFLAGS; CFLAGS=$GIF_CFLAGS
save_libs=$LIBS; LIBS=$GIF_LIBS
AC_CHECK_LIB(gif, DGifOpenFileName,
[AC_CHECK_HEADER(gif_lib.h,
GIF='gif'; libgif_LIBS='-lgif'; gif_ok=yes,
AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***))],
AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***))
AC_CHECK_LIB(ungif, DGifOpenFileName,
[AC_CHECK_HEADER(gif_lib.h,
GIF='ungif'; libgif_LIBS='-lungif'; gif_ok=yes,
AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***))],
AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***))
CFLAGS+=$save_cflags
LIBS+=$save_libs
fi
if test x$GIF != x; then
AC_SUBST(libgif_LIBS)
AC_DEFINE(HAVE_LIBGIF, 1, Define if gif support is available)
else
gif_ok="no (See http://sourceforge.net/projects/libgif)"
fi
dnl ---------------------------------------------------------------------
dnl Add extra compiler flags
dnl ---------------------------------------------------------------------

View file

@ -69,6 +69,9 @@ deps += [
dependency('libstartup-notification-1.0'),
]
libgif = c_compiler.find_library('libgif', required: false)
deps += [ libgif ]
check = dependency('check', version: '>= 0.11.0', required: get_option('check'))
header_conf = configuration_data()
@ -88,6 +91,7 @@ header_conf.set('GLIB_VERSION_MIN_REQUIRED', '(G_ENCODE_VERSION(@0@,@1@))'.forma
header_conf.set('GLIB_VERSION_MAX_ALLOWED', '(G_ENCODE_VERSION(@0@,@1@))'.format(glib_min_major, glib_min_minor))
header_conf.set('ENABLE_DRUN', get_option('drun'))
header_conf.set('HAVE_LIBGIF', libgif.found())
header_conf.set('WINDOW_MODE', get_option('window'))
header_conf.set_quoted('MANPAGE_PATH', join_paths(get_option('prefix'), get_option('mandir')))

View file

@ -35,6 +35,9 @@
#include <sys/stat.h>
#include <dirent.h>
#include <config.h>
#include "mode.h"
#include "helper.h"
#include "mode-private.h"
@ -341,7 +344,11 @@ static int file_browser_token_match ( const Mode *sw, rofi_int_matcher **tokens,
}
const char * const image_exts[] = {".png",".PNG",".jpg",".JPG",".jpeg",".JPEG",".svg",".SVG"};
const char * const image_exts[] = {".png",".PNG",".jpg",".JPG",".jpeg",".JPEG",".svg",".SVG"
#ifdef HAVE_LIBGIF
,".gif",".GIF"
#endif
};
static gboolean file_browser_is_image ( const char * const path )
{
if ( path == NULL ) {
@ -351,7 +358,7 @@ static gboolean file_browser_is_image ( const char * const path )
if ( suf == NULL ) {
return FALSE;
}
for ( uint32_t i = 0; i < (sizeof (image_exts)/sizeof(char*)); i++ ) {
for ( uint32_t i = 0; i < G_N_ELEMENTS(image_exts); i++ ) {
if ( g_strcmp0(suf,image_exts[i]) == 0 ) {
return TRUE;
}

View file

@ -28,6 +28,7 @@
/** The log domain of this Helper. */
#define G_LOG_DOMAIN "Helpers.IconFetcher"
#include "rofi-icon-fetcher.h"
#include "rofi-types.h"
#include "helper.h"
@ -44,6 +45,7 @@
#include <setjmp.h>
#include <config.h>
typedef struct
{
// Context for icon-themes.
@ -187,7 +189,7 @@ static void jpegErrorExit (j_common_ptr cinfo)
/* Create the message */
( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg);
g_warning ( jpegLastErrorMsg );
g_warning ( jpegLastErrorMsg, NULL );
/* Jump to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
@ -224,6 +226,68 @@ static cairo_surface_t* cairo_image_surface_create_from_jpeg ( const char* file
return surface;
}
#ifdef HAVE_LIBGIF
#include <gif_lib.h>
static cairo_surface_t* cairo_image_surface_create_from_gif(const char* file )
{
cairo_surface_t* img = NULL;
int err;
GifFileType* gif = DGifOpenFileName(file, &err);
if (!gif) {
g_warning( "[%i] %s", err, GifErrorString(err));
return NULL;
}
// decode with high-level API
if (DGifSlurp(gif) != GIF_OK) {
g_warning("Decoder error: %s", GifErrorString(gif->Error));
goto done;
}
if (!gif->SavedImages) {
g_warning("No saved images");
goto done;
}
// create canvas
img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gif->SWidth, gif->SHeight);
if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) {
g_warning("Unable to create surface: %s",
cairo_status_to_string(cairo_surface_status(img)));
cairo_surface_destroy(img);
img = NULL;
goto done;
}
// we don't support animation, show the first frame only
const GifImageDesc* frame = &gif->SavedImages->ImageDesc;
const GifColorType* colors = gif->SColorMap ? gif->SColorMap->Colors :
frame->ColorMap->Colors;
uint32_t* base = (uint32_t*)(cairo_image_surface_get_data(img) +
frame->Top * cairo_image_surface_get_stride(img));
for (int y = 0; y < frame->Height; ++y) {
uint32_t* pixel = base + y * gif->SWidth + frame->Left;
const uint8_t* raster = &gif->SavedImages->RasterBits[y * gif->SWidth];
for (int x = 0; x < frame->Width; ++x) {
const uint8_t color = raster[x];
if (color != gif->SBackGroundColor) {
const GifColorType* rgb = &colors[color];
*pixel = 0xff000000 |
rgb->Red << 16 | rgb->Green << 8 | rgb->Blue;
}
++pixel;
}
}
cairo_surface_mark_dirty(img);
done:
DGifCloseFile(gif, NULL);
return img;
}
#endif
static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpointer user_data )
{
g_debug ( "starting up icon fetching thread." );
@ -255,6 +319,11 @@ static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpoint
if ( g_str_has_suffix ( icon_path, ".png" ) || g_str_has_suffix ( icon_path, ".PNG" ) ) {
icon_surf = cairo_image_surface_create_from_png ( icon_path );
}
#ifdef HAVE_LIBGIF
else if ( g_str_has_suffix ( icon_path, ".gif" ) || g_str_has_suffix ( icon_path, ".GIF" ) ) {
icon_surf = cairo_image_surface_create_from_gif ( icon_path );
}
#endif
else if ( g_str_has_suffix ( icon_path, ".jpeg" ) || g_str_has_suffix ( icon_path, ".jpg" ) ||
g_str_has_suffix ( icon_path, ".JPEG" ) || g_str_has_suffix ( icon_path, ".JPG" )
) {