summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac30
-rw-r--r--thumbnailer/Makefile.am41
-rw-r--r--thumbnailer/eom-thumbnailer.c186
-rw-r--r--thumbnailer/eom-thumbnailer.thumbnailer.in4
6 files changed, 266 insertions, 1 deletions
diff --git a/.travis.yml b/.travis.yml
index a1c8ce0..965dba7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -71,6 +71,7 @@ requires:
- gcc
- git
- gobject-introspection
+ - imagemagick
- itstool
- lcms2
- libexif
@@ -101,6 +102,7 @@ requires:
- libgtk-3-dev
- libjpeg-dev
- liblcms2-dev
+ - libmagickwand-dev
- libmate-desktop-dev
- libpeas-dev
- librsvg2-dev
@@ -125,6 +127,7 @@ requires:
- git
- gobject-introspection-devel
- gtk3-devel
+ - ImageMagick-devel
- lcms2-devel
- libappstream-glib-devel
- libexif-devel
@@ -154,6 +157,7 @@ requires:
- libgtk-3-dev
- libjpeg-dev
- liblcms2-dev
+ - libmagickwand-dev
- libmate-desktop-dev
- libpeas-dev
- librsvg2-dev
diff --git a/Makefile.am b/Makefile.am
index d54477f..d9e2d75 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ if ENABLE_JPEG
jpeg_DIRS = jpegutils
endif
-SUBDIRS = po $(jpeg_DIRS) cut-n-paste src man plugins help data doc
+SUBDIRS = po $(jpeg_DIRS) cut-n-paste src man plugins help data doc thumbnailer
EXTRA_DIST = \
AUTHORS \
diff --git a/configure.ac b/configure.ac
index c181849..8da0751 100644
--- a/configure.ac
+++ b/configure.ac
@@ -93,6 +93,7 @@ GDKPIXBUF_REQUIRED=2.36.5
SHARED_MIME_INFO_REQUIRED=0.20
EXEMPI_REQUIRED=1.99.5
LIBPEAS_REQUIRED=1.8.0
+MAGICK_REQUIRED=6.2.6
PKG_CHECK_MODULES(GMODULE, gmodule-2.0, [GMODULE_ADD="gmodule-2.0"],[GMODULE_ADD=""])
EOM_MODULES="gtk+-3.0 >= $GTK_REQUIRED \
@@ -285,6 +286,34 @@ fi
AM_CONDITIONAL([HAVE_RSVG], [test "x$have_rsvg" = "xyes"])
+# ***********************
+# THUMBNAILER CFLAGS/LIBS
+# ***********************
+
+PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED)
+PKG_CHECK_MODULES(GIO, gio-2.0 >= $GLIB_REQUIRED)
+PKG_CHECK_MODULES(MAGICK, MagickWand >= $MAGICK_REQUIRED)
+
+CPPFLAGS_save="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $MAGICK_CFLAGS"
+AC_CHECK_HEADER([wand/MagickWand.h],
+ [have_im6="yes"],
+ [AC_CHECK_HEADER([MagickWand/MagickWand.h], [have_im7="yes"])])
+CPPFLAGS="$CPPFLAGS_save"
+
+if test "x$have_im6" = "xyes"; then
+ AC_DEFINE(HAVE_IMAGEMAGICK6,1, [Have ImageMagick 6])
+fi
+if test "x$have_im7" = "xyes"; then
+ AC_DEFINE(HAVE_IMAGEMAGICK7,1, [Have ImageMagick 7])
+fi
+
+THUMBNAILER_CFLAGS="$CFLAGS $GLIB_CFLAGS $GIO_CFLAGS $MAGICK_CFLAGS"
+AC_SUBST(THUMBNAILER_CFLAGS)
+
+THUMBNAILER_LIBS="$LIBS $GLIB_LIBS $GIO_LIBS $MAGICK_LIBS"
+AC_SUBST(THUMBNAILER_LIBS)
+
# ****************
# CFLAGS/LIBS init
# ****************
@@ -344,6 +373,7 @@ doc/reference/Makefile
doc/reference/version.xml
doc/reference/eom-docs.sgml
plugins/Makefile
+thumbnailer/Makefile
])
AC_OUTPUT
diff --git a/thumbnailer/Makefile.am b/thumbnailer/Makefile.am
new file mode 100644
index 0000000..4501ba7
--- /dev/null
+++ b/thumbnailer/Makefile.am
@@ -0,0 +1,41 @@
+NULL =
+
+bin_PROGRAMS = eom-thumbnailer
+
+eom_thumbnailer_SOURCES = \
+ eom-thumbnailer.c \
+ $(NULL)
+
+eom_thumbnailer_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(AM_CPPFLAGS) \
+ $(NULL)
+
+eom_thumbnailer_CFLAGS = \
+ $(THUMBNAILER_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ $(WARN_CFLAGS) \
+ $(AM_CFLAGS) \
+ $(NULL)
+
+eom_thumbnailer_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -lm \
+ $(THUMBNAILER_LIBS) \
+ $(NULL)
+
+thumbnailerdir = $(datadir)/thumbnailers
+thumbnailer_DATA = eom-thumbnailer.thumbnailer
+%.thumbnailer: %.thumbnailer.in
+ $(AM_V_GEN) sed -e 's|@bindir[@]|$(bindir)|g' $< > $@
+
+EXTRA_DIST = \
+ eom-thumbnailer.thumbnailer.in \
+ $(NULL)
+
+CLEANFILES = \
+ $(thumbnailer_DATA) \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/thumbnailer/eom-thumbnailer.c b/thumbnailer/eom-thumbnailer.c
new file mode 100644
index 0000000..dee7b82
--- /dev/null
+++ b/thumbnailer/eom-thumbnailer.c
@@ -0,0 +1,186 @@
+/* gcc eom-thumbnailer.c `pkg-config --cflags --libs glib-2.0 gio-2.0 MagickWand` -lm -o eom-thumbnailer */
+/*
+ * Copyright (C) 2020 MATE developers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Robert Buj <[email protected]>
+ *
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <math.h>
+#include <stdlib.h>
+
+#ifdef HAVE_IMAGEMAGICK7
+#include <MagickWand/MagickWand.h>
+#endif
+#ifdef HAVE_IMAGEMAGICK6
+#include <wand/magick_wand.h>
+#endif
+
+static int output_size = 256;
+static gboolean g_fatal_warnings = FALSE;
+static char **filenames = NULL;
+
+static char *
+get_target_uri (GFile *file)
+{
+ GFileInfo *info;
+ char *target;
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ if (info == NULL)
+ return NULL;
+ target = g_strdup (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI));
+ g_object_unref (info);
+
+ return target;
+}
+
+static char *
+get_target_path (GFile *input)
+{
+ if (g_file_has_uri_scheme (input, "trash") != FALSE ||
+ g_file_has_uri_scheme (input, "recent") != FALSE) {
+ GFile *file;
+ char *input_uri;
+ char *input_path;
+
+ input_uri = get_target_uri (input);
+ file = g_file_new_for_uri (input_uri);
+ g_free (input_uri);
+ input_path = g_file_get_path (file);
+ g_object_unref (file);
+ return input_path;
+ }
+ return g_file_get_path (input);
+}
+
+static const GOptionEntry entries[] = {
+ { "size", 's', 0, G_OPTION_ARG_INT, &output_size, "Size of the thumbnail in pixels", NULL },
+ {"g-fatal-warnings", '\0', 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL},
+ { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, "[INPUT FILE] [OUTPUT FILE]" },
+ { 0, '\0', 0, G_OPTION_ARG_NONE, 0, 0, 0 }
+};
+
+int main (int argc, char **argv)
+{
+ MagickBooleanType status;
+ MagickWand *magick_wand;
+ char *input_filename;
+ GError *error = NULL;
+ GOptionContext *context;
+ GFile *input;
+ const char *output;
+ size_t width, height;
+
+ /* Options parsing */
+ context = g_option_context_new ("- thumbnail images");
+ g_option_context_add_main_entries (context, entries, NULL);
+
+ (void) g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+ if (error) {
+ g_warning ("Couldn't parse command-line options: %s", error->message);
+ g_error_free (error);
+ goto arguments_error;
+ }
+
+ /* Set fatal warnings if required */
+ if (g_fatal_warnings) {
+ GLogLevelFlags fatal_mask;
+
+ fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+ fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+ g_log_set_always_fatal (fatal_mask);
+ }
+
+ if (filenames == NULL || g_strv_length (filenames) != 2) {
+ g_print ("Expects an input and an output file\n");
+ goto arguments_error;
+ }
+
+ if (output_size < 1) {
+ g_warning ("Size cannot be smaller than 1 pixel");
+ goto arguments_error;
+ }
+
+ input = g_file_new_for_commandline_arg (filenames[0]);
+ input_filename = get_target_path (input);
+ g_object_unref (input);
+ if (input_filename == NULL) {
+ g_warning ("Could not get file path for %s", filenames[0]);
+ goto arguments_error;
+ }
+
+ output = filenames[1];
+
+ /* Read an image */
+ MagickWandGenesis ();
+ magick_wand = NewMagickWand ();
+ status = MagickReadImage (magick_wand, input_filename);
+ g_free (input_filename);
+ if (status == MagickFalse) {
+ g_warning ("Could not load input file %s", filenames[0]);
+ goto imagemagick_error;
+ }
+
+ /* Get the image's width and height */
+ width = MagickGetImageWidth (magick_wand);
+ height = MagickGetImageHeight (magick_wand);
+
+ /* Thumbnail */
+ if ((height > output_size) || (width > output_size)) {
+ double scale;
+ scale = (double) output_size / MAX (width, height);
+ MagickThumbnailImage (magick_wand,
+ (size_t) floor (width * scale + 0.5),
+ (size_t) floor (height * scale + 0.5));
+ }
+
+ /* Write the image then destroy it */
+ status = MagickWriteImages (magick_wand, output, MagickTrue);
+ if (status == MagickFalse) {
+ g_warning ("Could not save output file %s", output);
+ goto imagemagick_error;
+ }
+ g_strfreev (filenames);
+ if (magick_wand)
+ DestroyMagickWand (magick_wand);
+ MagickWandTerminus ();
+
+ return 0;
+
+arguments_error:
+ if (filenames)
+ g_strfreev (filenames);
+ return 1;
+
+imagemagick_error:
+ g_strfreev (filenames);
+ if (magick_wand)
+ DestroyMagickWand (magick_wand);
+ return 1;
+}
diff --git a/thumbnailer/eom-thumbnailer.thumbnailer.in b/thumbnailer/eom-thumbnailer.thumbnailer.in
new file mode 100644
index 0000000..1583b4f
--- /dev/null
+++ b/thumbnailer/eom-thumbnailer.thumbnailer.in
@@ -0,0 +1,4 @@
+[Thumbnailer Entry]
+TryExec=@bindir@/eom-thumbnailer
+Exec=@bindir@/eom-thumbnailer -s %s %u %o
+MimeType=image/webp;