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:
parent
d8a420c952
commit
5994df7f04
5 changed files with 115 additions and 3 deletions
|
@ -168,6 +168,7 @@ rofi_LDADD=\
|
|||
$(cairo_LIBS)\
|
||||
$(librsvg_LIBS)\
|
||||
$(libjpeg_LIBS)\
|
||||
$(libgif_LIBS)\
|
||||
$(LIBS)
|
||||
|
||||
##
|
||||
|
|
31
configure.ac
31
configure.ac
|
@ -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 ---------------------------------------------------------------------
|
||||
|
|
|
@ -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')))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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" )
|
||||
) {
|
||||
|
|
Loading…
Reference in a new issue