summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Abdallah <ali.abdallah@suse.com>2020-11-15 17:21:27 +0100
committerAli Abdallah <ali.abdallah@suse.com>2020-11-15 17:21:27 +0100
commit0bdf4bccc18e0184ea03426a27c9df2c0f186817 (patch)
treed5cb53f68602766a764bc800b3b6473192fe0641
parenteac67eb8c6f5c53a78d4f1630b44508aa7432611 (diff)
parentb17009e5f5d8f3b0c011f177ab2e513adb51495c (diff)
downloadtumbler-0bdf4bccc18e0184ea03426a27c9df2c0f186817.tar.gz
Merge branch 'OlivierDuchateau/tumbler-gepub-thumbnailer'
-rw-r--r--acinclude.m421
-rw-r--r--configure.ac7
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/gepub-thumbnailer/Makefile.am45
-rw-r--r--plugins/gepub-thumbnailer/gepub-thumbnailer-plugin.c93
-rw-r--r--plugins/gepub-thumbnailer/gepub-thumbnailer-provider.c128
-rw-r--r--plugins/gepub-thumbnailer/gepub-thumbnailer-provider.h44
-rw-r--r--plugins/gepub-thumbnailer/gepub-thumbnailer.c290
-rw-r--r--plugins/gepub-thumbnailer/gepub-thumbnailer.h44
-rw-r--r--po/POTFILES.in1
-rw-r--r--tumblerd/tumbler.rc8
11 files changed, 682 insertions, 0 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 596917b..cd070a0 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -304,3 +304,24 @@ AM_CONDITIONAL([TUMBLER_DESKTOP_THUMBNAILER], [test x"$ac_tumbler_desktop_thumbn
AC_MSG_RESULT([$ac_tumbler_desktop_thumbnailer])
])
+dnl TUMBLER_GEPUB_THUMBNAILER()
+dnl
+dnl Check whether to build the libgepub thumbnailer plugin.
+dnl
+AC_DEFUN([TUMBLER_GEPUB_THUMBNAILER],
+[
+AC_ARG_ENABLE([gepub-thumbnailer], [AC_HELP_STRING([--disable-gepub-thumbnailer], [Don't build the libgepub thumbnailer plugin])],
+ [ac_tumbler_gepub_thumbnailer=$enableval], [ac_tumbler_gepub_thumbnailer=yes])
+if test x"$ac_tumbler_gepub_thumbnailer" = x"yes"; then
+ dnl Check for gdk-pixbuf
+ PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0 >= 2.14],
+ [
+ dnl Check for libgepub
+ PKG_CHECK_MODULES([GEPUB], [libgepub-0.6 >= 0.6.0], [], [ac_tumbler_gepub_thumbnailer=no])
+ ], [ac_tumbler_gepub_thumbnailer=no])
+fi
+
+AC_MSG_CHECKING([whether to build the libgepub thumbnailer plugin])
+AM_CONDITIONAL([TUMBLER_GEPUB_THUMBNAILER], [test x"$ac_tumbler_gepub_thumbnailer" = x"yes"])
+AC_MSG_RESULT([$ac_tumbler_gepub_thumbnailer])
+])
diff --git a/configure.ac b/configure.ac
index c3a04be..71ffc22 100644
--- a/configure.ac
+++ b/configure.ac
@@ -163,6 +163,7 @@ TUMBLER_POPPLER_THUMBNAILER()
TUMBLER_RAW_THUMBNAILER()
TUMBLER_XDG_CACHE()
TUMBLER_DESKTOP_THUMBNAILER()
+TUMBLER_GEPUB_THUMBNAILER()
dnl ***********************************
dnl *** Check for debugging support ***
@@ -200,6 +201,7 @@ plugins/poppler-thumbnailer/Makefile
plugins/raw-thumbnailer/Makefile
plugins/xdg-cache/Makefile
plugins/desktop-thumbnailer/Makefile
+plugins/gepub-thumbnailer/Makefile
po/Makefile.in
tumbler/Makefile
tumbler/tumbler-1.pc
@@ -273,4 +275,9 @@ echo " * Loading thumbnailers from .thumbnailer files: yes"
else
echo " * Loading thumbnailers from .thumbnailer files: no"
fi
+if test x"$ac_tumbler_gepub_thumbnailer" = x"yes"; then
+echo " * EPUB thumbnailer using libgepub: yes"
+else
+echo " * EPUB thumbnailer using libgepub: no"
+fi
echo
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index f2b5307..97eaa2b 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -28,4 +28,5 @@ SUBDIRS = \
poppler-thumbnailer \
raw-thumbnailer \
desktop-thumbnailer \
+ gepub-thumbnailer \
xdg-cache
diff --git a/plugins/gepub-thumbnailer/Makefile.am b/plugins/gepub-thumbnailer/Makefile.am
new file mode 100644
index 0000000..a3737db
--- /dev/null
+++ b/plugins/gepub-thumbnailer/Makefile.am
@@ -0,0 +1,45 @@
+if TUMBLER_GEPUB_THUMBNAILER
+
+tumbler_plugindir = $(libdir)/tumbler-$(TUMBLER_VERSION_API)/plugins
+tumbler_plugin_LTLIBRARIES = \
+ tumbler-gepub-thumbnailer.la
+
+tumbler_gepub_thumbnailer_la_SOURCES = \
+ gepub-thumbnailer-plugin.c \
+ gepub-thumbnailer-provider.c \
+ gepub-thumbnailer-provider.h \
+ gepub-thumbnailer.c \
+ gepub-thumbnailer.h
+
+tumbler_gepub_thumbnailer_la_CFLAGS = \
+ -I$(top_builddir) \
+ -I$(top_builddir)/plugins \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/plugins \
+ -DG_LOG_DOMAIN=\"tumbler-gepub-thumbnailer\" \
+ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+ $(GDK_PIXBUF_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GEPUB_CFLAGS) \
+ $(PLATFORM_CFLAGS) \
+ $(PLATFORM_CPPFLAGS)
+
+tumbler_gepub_thumbnailer_la_LDFLAGS = \
+ -avoid-version \
+ -export-dynamic \
+ -module \
+ $(PLATFORM_LDFLAGS)
+
+tumbler_gepub_thumbnailer_la_LIBADD = \
+ $(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la \
+ $(GDK_PIXBUF_LIBS) \
+ $(GIO_LIBS) \
+ $(GLIB_LIBS) \
+ $(GEPUB_LIBS) \
+ -lm
+
+tumbler_gepub_thumbnailer_la_DEPENDENCIES = \
+ $(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la
+
+endif
diff --git a/plugins/gepub-thumbnailer/gepub-thumbnailer-plugin.c b/plugins/gepub-thumbnailer/gepub-thumbnailer-plugin.c
new file mode 100644
index 0000000..8f17a46
--- /dev/null
+++ b/plugins/gepub-thumbnailer/gepub-thumbnailer-plugin.c
@@ -0,0 +1,93 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * Copyright (c) 2020, Olivier Duchateau <duchateau.olivier@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include <tumbler/tumbler.h>
+
+#include "gepub-thumbnailer-provider.h"
+#include "gepub-thumbnailer.h"
+
+
+
+G_MODULE_EXPORT void tumbler_plugin_initialize (TumblerProviderPlugin *plugin);
+G_MODULE_EXPORT void tumbler_plugin_shutdown (void);
+G_MODULE_EXPORT void tumbler_plugin_get_types (const GType **types,
+ gint *n_types);
+
+
+
+static GType type_list[1];
+
+
+
+void
+tumbler_plugin_initialize (TumblerProviderPlugin *plugin)
+{
+ const gchar *mismatch;
+
+ /* verify that the tumbler versions are compatible */
+ mismatch = tumbler_check_version (TUMBLER_MAJOR_VERSION,
+ TUMBLER_MINOR_VERSION,
+ TUMBLER_MICRO_VERSION);
+ if (G_UNLIKELY (mismatch != NULL))
+ {
+ g_warning (_("Version mismatch: %s"), mismatch);
+ return;
+ }
+
+#ifdef DEBUG
+ g_print ("Initializing the Tumbler Gepub Thumbnailer plugin\n");
+#endif
+
+ /* register the types provided by this plugin */
+ gepub_thumbnailer_register (plugin);
+ gepub_thumbnailer_provider_register (plugin);
+
+ /* set up the plugin provider type list */
+ type_list[0] = TYPE_GEPUB_THUMBNAILER_PROVIDER;
+}
+
+
+
+void
+tumbler_plugin_shutdown (void)
+{
+#ifdef DEBUG
+ g_print ("Shutting down the Tumbler Gepub Thumbnailer plugin\n");
+#endif
+}
+
+
+
+void
+tumbler_plugin_get_types (const GType **types,
+ gint *n_types)
+{
+ *types = type_list;
+ *n_types = G_N_ELEMENTS (type_list);
+}
diff --git a/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.c b/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.c
new file mode 100644
index 0000000..2204bd3
--- /dev/null
+++ b/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.c
@@ -0,0 +1,128 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * Copyright (c) 2020, Olivier Duchateau <duchateau.olivier@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <tumbler/tumbler.h>
+
+#include "gepub-thumbnailer-provider.h"
+#include "gepub-thumbnailer.h"
+
+
+
+static void gepub_thumbnailer_provider_thumbnailer_provider_init (TumblerThumbnailerProviderIface *iface);
+static GList *gepub_thumbnailer_provider_get_thumbnailers (TumblerThumbnailerProvider *provider);
+
+
+
+struct _GepubThumbnailerProviderClass
+{
+ GObjectClass __parent__;
+};
+
+struct _GepubThumbnailerProvider
+{
+ GObject __parent__;
+};
+
+
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (GepubThumbnailerProvider,
+ gepub_thumbnailer_provider,
+ G_TYPE_OBJECT,
+ 0,
+ TUMBLER_ADD_INTERFACE (TUMBLER_TYPE_THUMBNAILER_PROVIDER,
+ gepub_thumbnailer_provider_thumbnailer_provider_init));
+
+
+
+void
+gepub_thumbnailer_provider_register (TumblerProviderPlugin *plugin)
+{
+ gepub_thumbnailer_provider_register_type (G_TYPE_MODULE (plugin));
+}
+
+
+
+static void
+gepub_thumbnailer_provider_class_init (GepubThumbnailerProviderClass *klass)
+{
+}
+
+
+
+static void
+gepub_thumbnailer_provider_class_finalize (GepubThumbnailerProviderClass *klass)
+{
+}
+
+
+
+static void
+gepub_thumbnailer_provider_thumbnailer_provider_init (TumblerThumbnailerProviderIface *iface)
+{
+ iface->get_thumbnailers = gepub_thumbnailer_provider_get_thumbnailers;
+}
+
+
+
+static void
+gepub_thumbnailer_provider_init (GepubThumbnailerProvider *provider)
+{
+}
+
+
+
+static GList *
+gepub_thumbnailer_provider_get_thumbnailers (TumblerThumbnailerProvider *provider)
+{
+ GepubThumbnailer *thumbnailer;
+ GList *thumbnailers = NULL;
+ static const gchar *mime_types[] =
+ {
+ "application/epub",
+ "application/epub+zip",
+ NULL
+ };
+ GStrv uri_schemes;
+
+ /* determine which URI schemes are supported by GIO */
+ uri_schemes = tumbler_util_get_supported_uri_schemes ();
+
+ /* create the pixbuf thumbnailer */
+ thumbnailer = g_object_new (TYPE_GEPUB_THUMBNAILER,
+ "uri-schemes", uri_schemes,
+ "mime-types", mime_types,
+ NULL);
+
+ /* add the thumbnailer to the list */
+ thumbnailers = g_list_append (thumbnailers, thumbnailer);
+
+ /* free URI schemes and MIME types */
+ g_strfreev (uri_schemes);
+
+ return thumbnailers;
+}
diff --git a/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.h b/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.h
new file mode 100644
index 0000000..57ee33b
--- /dev/null
+++ b/plugins/gepub-thumbnailer/gepub-thumbnailer-provider.h
@@ -0,0 +1,44 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * Copyright (c) 2020, Olivier duchateau <duchateau.olivier@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GEPUB_THUMBNAILER_PROVIDER_H__
+#define __GEPUB_THUMBNAILER_PROVIDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+#define TYPE_GEPUB_THUMBNAILER_PROVIDER (gepub_thumbnailer_provider_get_type ())
+#define GEPUB_THUMBNAILER_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GEPUB_THUMBNAILER_PROVIDER, GepubThumbnailerProvider))
+#define GEPUB_THUMBNAILER_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GEPUB_THUMBNAILER_PROVIDER, GepubThumbnailerProviderClass))
+#define IS_GEPUB_THUMBNAILER_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GEPUB_THUMBNAILER_PROVIDER))
+#define IS_GEPUB_THUMBNAILER_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GEPUB_THUMBNAILER_PROVIDER))
+#define GEPUB_THUMBNAILER_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_GEPUB_THUMBNAILER_PROVIDER, GepubThumbnailerProviderClass))
+
+typedef struct _GepubThumbnailerProviderClass GepubThumbnailerProviderClass;
+typedef struct _GepubThumbnailerProvider GepubThumbnailerProvider;
+
+GType gepub_thumbnailer_provider_get_type (void) G_GNUC_CONST;
+void gepub_thumbnailer_provider_register (TumblerProviderPlugin *plugin);
+
+G_END_DECLS;
+
+#endif /* !__GEPUB_THUMBNAILER_PROVIDER_H__ */
diff --git a/plugins/gepub-thumbnailer/gepub-thumbnailer.c b/plugins/gepub-thumbnailer/gepub-thumbnailer.c
new file mode 100644
index 0000000..acd0fd3
--- /dev/null
+++ b/plugins/gepub-thumbnailer/gepub-thumbnailer.c
@@ -0,0 +1,290 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * Copyright (c) 2020, Olivier Duchateau <duchateau.olivier@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <tumbler/tumbler.h>
+#include <gepub.h>
+
+#include "gepub-thumbnailer.h"
+
+
+static void gepub_thumbnailer_create (TumblerAbstractThumbnailer *thumbnailer,
+ GCancellable *cancellable,
+ TumblerFileInfo *info);
+
+
+
+struct _GepubThumbnailerClass
+{
+ TumblerAbstractThumbnailerClass __parent__;
+};
+
+struct _GepubThumbnailer
+{
+ TumblerAbstractThumbnailer __parent__;
+};
+
+
+
+G_DEFINE_DYNAMIC_TYPE (GepubThumbnailer,
+ gepub_thumbnailer,
+ TUMBLER_TYPE_ABSTRACT_THUMBNAILER);
+
+
+
+void
+gepub_thumbnailer_register (TumblerProviderPlugin *plugin)
+{
+ gepub_thumbnailer_register_type (G_TYPE_MODULE (plugin));
+}
+
+
+
+static void
+gepub_thumbnailer_class_init (GepubThumbnailerClass *klass)
+{
+ TumblerAbstractThumbnailerClass *abstractthumbnailer_class;
+
+ abstractthumbnailer_class = TUMBLER_ABSTRACT_THUMBNAILER_CLASS (klass);
+ abstractthumbnailer_class->create = gepub_thumbnailer_create;
+}
+
+
+
+static void
+gepub_thumbnailer_class_finalize (GepubThumbnailerClass *klass)
+{
+}
+
+
+
+static void
+gepub_thumbnailer_init (GepubThumbnailer *thumbnailer)
+{
+}
+
+
+
+static void
+gepub_thumbnailer_size_prepared (GdkPixbufLoader *loader,
+ gint source_width,
+ gint source_height,
+ TumblerThumbnail *thumbnail)
+{
+ TumblerThumbnailFlavor *flavor;
+ gint dest_width;
+ gint dest_height;
+ gdouble hratio;
+ gdouble wratio;
+
+ g_return_if_fail (GDK_IS_PIXBUF_LOADER (loader));
+ g_return_if_fail (TUMBLER_IS_THUMBNAIL (thumbnail));
+
+ flavor = tumbler_thumbnail_get_flavor (thumbnail);
+ tumbler_thumbnail_flavor_get_size (flavor, &dest_width, &dest_height);
+ g_object_unref (flavor);
+
+ if (source_width <= dest_width && source_height <= dest_height)
+ {
+ /* do not scale the image */
+ dest_width = source_width;
+ dest_height = source_height;
+ }
+ else
+ {
+ /* determine which axis needs to be scaled down more */
+ wratio = (gdouble) source_width / (gdouble) dest_width;
+ hratio = (gdouble) source_height / (gdouble) dest_height;
+
+ /* adjust the other axis */
+ if (hratio > wratio)
+ dest_width = rint (source_width / hratio);
+ else
+ dest_height = rint (source_height / wratio);
+ }
+
+ gdk_pixbuf_loader_set_size (loader, MAX (dest_width, 1),
+ MAX (dest_height, 1));
+}
+
+
+
+static GdkPixbuf *
+gepub_thumbnailer_create_from_mime (gchar *mime_type,
+ GBytes *content,
+ TumblerThumbnail *thumbnail,
+ GError **error)
+{
+ GdkPixbufLoader *loader;
+ GdkPixbuf *pixbuf = NULL;
+ GError *err = NULL;
+
+ g_return_val_if_fail (TUMBLER_IS_THUMBNAIL (thumbnail), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* allow only some mime types */
+ if (g_strcmp0 (mime_type, "image/png") == 0 ||
+ g_strcmp0 (mime_type, "image/jpeg") == 0 ||
+ g_strcmp0 (mime_type, "image/gif") == 0)
+ {
+ loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, &err);
+ g_signal_connect (loader, "size-prepared",
+ G_CALLBACK (gepub_thumbnailer_size_prepared),
+ thumbnail);
+ if (gdk_pixbuf_loader_write_bytes (loader, content, &err))
+ {
+ if (gdk_pixbuf_loader_close (loader, &err))
+ {
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf != NULL)
+ g_object_ref (G_OBJECT (pixbuf));
+ }
+ }
+ else
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ g_object_unref (loader);
+
+ if (err != NULL)
+ g_propagate_error (error, err);
+ }
+ return pixbuf;
+}
+
+
+
+static void
+gepub_thumbnailer_create (TumblerAbstractThumbnailer *thumbnailer,
+ GCancellable *cancellable,
+ TumblerFileInfo *info)
+{
+ TumblerImageData data;
+ TumblerThumbnail *thumbnail;
+ const gchar *uri;
+ GFile *file;
+ GError *error = NULL;
+ gchar *path;
+ GdkPixbuf *pixbuf = NULL;
+ GepubDoc *doc;
+ gchar *cover;
+ gchar *cover_mime;
+ GBytes *content;
+
+ g_return_if_fail (IS_GEPUB_THUMBNAILER (thumbnailer));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (TUMBLER_IS_FILE_INFO (info));
+
+ /* do nothing if cancelled */
+ if (g_cancellable_is_cancelled (cancellable))
+ return;
+
+ uri = tumbler_file_info_get_uri (info);
+ file = g_file_new_for_uri (uri);
+
+ if (g_file_is_native (file))
+ {
+ /* try to load the EPUB file */
+ path = g_file_get_path (file);
+ doc = gepub_doc_new (path, &error);
+ if (error != NULL)
+ {
+ g_signal_emit_by_name (thumbnailer, "error", uri,
+ error->code, error->message);
+ g_error_free (error);
+
+ g_free (path);
+ g_object_unref (file);
+ return;
+ }
+
+ /* find cover file and its mime type */
+ cover = gepub_doc_get_cover (doc);
+ cover_mime = gepub_doc_get_resource_mime_by_id (doc, cover);
+
+ if (cover_mime == NULL)
+ {
+ g_signal_emit_by_name (thumbnailer, "error", uri,
+ TUMBLER_ERROR_NO_CONTENT,
+ "Cover not found");
+
+ g_free (cover);
+ g_free (path);
+ g_object_unref (doc);
+ g_object_unref (file);
+ return;
+ }
+
+ /* content of cover image */
+ content = gepub_doc_get_resource_by_id (doc, cover);
+ g_free (cover);
+
+ thumbnail = tumbler_file_info_get_thumbnail (info);
+
+ pixbuf = gepub_thumbnailer_create_from_mime (cover_mime, content,
+ thumbnail,
+ &error);
+ g_free (cover_mime);
+ g_free (path);
+ g_object_unref (doc);
+ }
+ g_object_unref (file);
+
+ if (pixbuf != NULL)
+ {
+ data.data = gdk_pixbuf_get_pixels (pixbuf);
+ data.has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ data.bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
+ data.width = gdk_pixbuf_get_width (pixbuf);
+ data.height = gdk_pixbuf_get_height (pixbuf);
+ data.rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ data.colorspace = (TumblerColorspace) gdk_pixbuf_get_colorspace (pixbuf);
+
+ tumbler_thumbnail_save_image_data (thumbnail, &data,
+ tumbler_file_info_get_mtime (info),
+ NULL, &error);
+
+ g_object_unref (pixbuf);
+ }
+
+ if (error != NULL)
+ {
+ g_signal_emit_by_name (thumbnailer, "error", uri, error->code,
+ error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_signal_emit_by_name (thumbnailer, "ready", uri);
+ }
+
+ g_object_unref (thumbnail);
+}
diff --git a/plugins/gepub-thumbnailer/gepub-thumbnailer.h b/plugins/gepub-thumbnailer/gepub-thumbnailer.h
new file mode 100644
index 0000000..a19266b
--- /dev/null
+++ b/plugins/gepub-thumbnailer/gepub-thumbnailer.h
@@ -0,0 +1,44 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * Copyright (c) 2020, Olivier Duchateau <duchateau.olivier@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GEPUB_THUMBNAILER_H__
+#define __GEPUB_THUMBNAILER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+#define TYPE_GEPUB_THUMBNAILER (gepub_thumbnailer_get_type ())
+#define GEPUB_THUMBNAILER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_GEPUB_THUMBNAILER, GepubThumbnailer))
+#define GEPUB_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_GEPUB_THUMBNAILER, GepubThumbnailerClass))
+#define IS_GEPUB_THUMBNAILER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_GEPUB_THUMBNAILER))
+#define IS_GEPUB_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_GEPUB_THUMBNAILER))
+#define GEPUB_THUMBNAILER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_GEPUB_THUMBNAILER, GepubThumbnailerClass))
+
+typedef struct _GepubThumbnailerClass GepubThumbnailerClass;
+typedef struct _GepubThumbnailer GepubThumbnailer;
+
+GType gepub_thumbnailer_get_type (void) G_GNUC_CONST;
+void gepub_thumbnailer_register (TumblerProviderPlugin *plugin);
+
+G_END_DECLS;
+
+#endif /* !__GEPUB_THUMBNAILER_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6def9ac..4a7ddd4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -47,3 +47,4 @@ plugins/xdg-cache/xdg-cache-cache.c
plugins/desktop-thumbnailer/desktop-thumbnailer.c
plugins/desktop-thumbnailer/desktop-thumbnailer-plugin.c
plugins/desktop-thumbnailer/desktop-thumbnailer-provider.c
+plugins/gepub-thumbnailer/gepub-thumbnailer-plugin.c
diff --git a/tumblerd/tumbler.rc b/tumblerd/tumbler.rc
index 6d18e25..98334aa 100644
--- a/tumblerd/tumbler.rc
+++ b/tumblerd/tumbler.rc
@@ -116,3 +116,11 @@ Priority=1
Locations=
Excludes=
MaxFileSize=2147483648
+
+# Epub thumbnailer
+[EpubThumbnailer]
+Disabled=false
+Priority=1
+Locations=
+Excludes=
+MaxFileSize=209715200