[gthumb] added ability to load WebP images
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] added ability to load WebP images
- Date: Sun, 26 Aug 2012 09:53:21 +0000 (UTC)
commit 00d162db01edf5a66bdfc7c3b37a0dc73bd25dd3
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Aug 25 21:02:33 2012 +0200
added ability to load WebP images
[new feature]
configure.ac | 24 ++++
extensions/cairo_io/Makefile.am | 8 +-
extensions/cairo_io/cairo-image-surface-webp.c | 134 ++++++++++++++++++++
extensions/cairo_io/cairo-image-surface-webp.h | 41 ++++++
extensions/cairo_io/main.c | 15 ++-
.../image_viewer/gth-metadata-provider-image.c | 31 ++++-
gthumb/Makefile.am | 1 +
gthumb/glib-utils.c | 19 +++-
gthumb/glib-utils.h | 1 +
gthumb/gth-file-data.c | 4 +-
gthumb/gth-metadata-provider.c | 17 +++
11 files changed, 280 insertions(+), 15 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c77e1ff..abaadfe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ GNOME_KEYRING_REQUIRED=3.2.0
LIBBRASERO_REQUIRED=3.2.0
LIBCHAMPLAIN_REQUIRED=0.12.0
LIBRSVG_REQUIRED=2.34.0
+LIBWEBP_REQUIRED=0.2.0
dnl ===========================================================================
@@ -418,6 +419,28 @@ AC_SUBST(TIFF_LIBS)
dnl ===========================================================================
+AC_ARG_ENABLE([libwebp],
+ [AS_HELP_STRING([--enable-libwebp],[compile code that uses the libwebp library])],,
+ [enable_libwebp=yes])
+
+if test x$enable_libwebp = xyes ; then
+ PKG_CHECK_MODULES(LIBWEBP,
+ [libwebp >= $LIBWEBP_REQUIRED],
+ [enable_libwebp=yes],
+ [enable_libwebp=no])
+fi
+if test x$enable_libwebp = xyes ; then
+ AC_DEFINE(HAVE_LIBWEBP, 1, [Define to 1 if libwebp support is included])
+fi
+
+AC_SUBST(LIBWEBP_LIBS)
+AC_SUBST(LIBWEBP_CFLAGS)
+AM_CONDITIONAL(ENABLE_LIBWEBP, test "x$enable_libwebp" = xyes)
+
+AC_DEFINE(WEBP_IS_UNKNOWN_TO_GLIB, 1, [Define to 1 if webp images area not recognized by the glib functions])
+
+dnl ===========================================================================
+
AC_MSG_CHECKING(liboperaw)
AC_ARG_ENABLE([libopenraw],
[AS_HELP_STRING([--enable-libopenraw],[use the libopenraw library to read raw files [default=no]])],,
@@ -739,4 +762,5 @@ Configuration:
SM client support : ${with_smclient}
Map support : ${enable_libchamplain}
SVG support : ${enable_librsvg}
+ WebP support : ${enable_libwebp}
"
diff --git a/extensions/cairo_io/Makefile.am b/extensions/cairo_io/Makefile.am
index 4278ed0..9e822d1 100644
--- a/extensions/cairo_io/Makefile.am
+++ b/extensions/cairo_io/Makefile.am
@@ -55,9 +55,15 @@ libcairo_io_la_SOURCES += \
cairo-image-surface-svg.h
endif
+if ENABLE_LIBWEBP
+libcairo_io_la_SOURCES += \
+ cairo-image-surface-webp.c \
+ cairo-image-surface-webp.h
+endif
+
libcairo_io_la_CFLAGS = $(GTHUMB_CFLAGS) $(JPEG_CFLAGS) $(LIBRSVG_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
libcairo_io_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
-libcairo_io_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LIBRSVG_LIBS)
+libcairo_io_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LIBRSVG_LIBS) $(LIBWEBP_LIBS)
if ENABLE_JPEG_TOOLS
libcairo_io_la_LIBADD += ../jpeg_utils/libjpeg_utils.la
endif
diff --git a/extensions/cairo_io/cairo-image-surface-webp.c b/extensions/cairo_io/cairo-image-surface-webp.c
new file mode 100644
index 0000000..965d0d3
--- /dev/null
+++ b/extensions/cairo_io/cairo-image-surface-webp.c
@@ -0,0 +1,134 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <webp/decode.h>
+#include <gthumb.h>
+#include "cairo-image-surface-webp.h"
+
+
+#define BUFFER_SIZE (16*1024)
+
+
+GthImage *
+_cairo_image_surface_create_from_webp (GInputStream *istream,
+ GthFileData *file_data,
+ int requested_size,
+ int *original_width,
+ int *original_height,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GthImage *image;
+ WebPDecoderConfig config;
+ guchar *buffer;
+ gssize bytes_read;
+ int width, height;
+ cairo_surface_t *surface;
+ cairo_surface_metadata_t *metadata;
+ WebPIDecoder *idec;
+
+ image = gth_image_new ();
+
+ if (! WebPInitDecoderConfig (&config))
+ return image;
+
+ buffer = g_new (guchar, BUFFER_SIZE);
+ bytes_read = g_input_stream_read (istream,
+ buffer,
+ BUFFER_SIZE,
+ cancellable,
+ error);
+
+ if (WebPGetFeatures (buffer, bytes_read, &config.input) != VP8_STATUS_OK) {
+ g_free (buffer);
+ return image;
+ }
+
+ width = config.input.width;
+ height = config.input.height;
+
+ if (original_width != NULL)
+ *original_width = width;
+ if (original_height != NULL)
+ *original_height = height;
+
+#if SCALING_WORKS
+ if (requested_size > 0)
+ scale_keeping_ratio (&width, &height, requested_size, requested_size, FALSE);
+#endif
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ metadata = _cairo_image_surface_get_metadata (surface);
+ metadata->has_alpha = (config.input.has_alpha);
+
+ cairo_surface_flush (surface);
+
+ config.options.no_fancy_upsampling = 1;
+
+#if SCALING_WORKS
+ if (requested_size > 0) {
+ config.options.use_scaling = 1;
+ config.options.scaled_width = width;
+ config.options.scaled_height = height;
+ }
+#endif
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ config.output.colorspace = MODE_BGRA;
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+ config.output.colorspace = MODE_ARGB
+#endif
+ config.output.u.RGBA.rgba = (uint8_t *) cairo_image_surface_get_data (surface);
+ config.output.u.RGBA.stride = cairo_image_surface_get_stride (surface);
+ config.output.u.RGBA.size = cairo_image_surface_get_stride (surface) * height;
+ config.output.is_external_memory = 1;
+
+ idec = WebPINewDecoder (&config.output);
+ if (idec == NULL) {
+ g_free (buffer);
+ return image;
+ }
+
+ do {
+ VP8StatusCode status = WebPIAppend (idec, buffer, bytes_read);
+ if ((status != VP8_STATUS_OK) && (status != VP8_STATUS_SUSPENDED))
+ break;
+ }
+ while ((bytes_read = g_input_stream_read (istream,
+ buffer,
+ BUFFER_SIZE,
+ cancellable,
+ error)) > 0);
+
+ cairo_surface_mark_dirty (surface);
+ if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
+ gth_image_set_cairo_surface (image, surface);
+
+ WebPIDelete (idec);
+ WebPFreeDecBuffer (&config.output);
+
+ g_free (buffer);
+
+ return image;
+}
diff --git a/extensions/cairo_io/cairo-image-surface-webp.h b/extensions/cairo_io/cairo-image-surface-webp.h
new file mode 100644
index 0000000..d9c952b
--- /dev/null
+++ b/extensions/cairo_io/cairo-image-surface-webp.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAIRO_IMAGE_SURFACE_WEBP_H
+#define CAIRO_IMAGE_SURFACE_WEBP_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+GthImage * _cairo_image_surface_create_from_webp (GInputStream *istream,
+ GthFileData *file_data,
+ int requested_size,
+ int *original_width,
+ int *original_height,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* CAIRO_IMAGE_SURFACE_WEBP_H */
diff --git a/extensions/cairo_io/main.c b/extensions/cairo_io/main.c
index 249fb22..a685ecc 100644
--- a/extensions/cairo_io/main.c
+++ b/extensions/cairo_io/main.c
@@ -25,10 +25,12 @@
#include "cairo-image-surface-jpeg.h"
#include "cairo-image-surface-png.h"
#include "cairo-image-surface-svg.h"
+#include "cairo-image-surface-webp.h"
#include "gth-image-saver-jpeg.h"
#include "gth-image-saver-png.h"
#include "gth-image-saver-tga.h"
#include "gth-image-saver-tiff.h"
+/*#include "gth-image-saver-webp.h"*/
#include "preferences.h"
@@ -36,13 +38,11 @@ G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
#ifdef HAVE_LIBJPEG
-
gth_main_register_image_loader_func (_cairo_image_surface_create_from_jpeg,
GTH_IMAGE_FORMAT_CAIRO_SURFACE,
"image/jpeg",
NULL);
gth_main_register_type ("image-saver", GTH_TYPE_IMAGE_SAVER_JPEG);
-
#endif
gth_main_register_image_loader_func (_cairo_image_surface_create_from_png,
@@ -51,17 +51,24 @@ gthumb_extension_activate (void)
NULL);
#ifdef HAVE_LIBRSVG
-
gth_main_register_image_loader_func (_cairo_image_surface_create_from_svg,
GTH_IMAGE_FORMAT_CAIRO_SURFACE,
"image/svg+xml",
NULL);
-
#endif
gth_main_register_type ("image-saver", GTH_TYPE_IMAGE_SAVER_PNG);
gth_main_register_type ("image-saver", GTH_TYPE_IMAGE_SAVER_TGA);
gth_main_register_type ("image-saver", GTH_TYPE_IMAGE_SAVER_TIFF);
+
+#ifdef HAVE_LIBWEBP
+ gth_main_register_image_loader_func (_cairo_image_surface_create_from_webp,
+ GTH_IMAGE_FORMAT_CAIRO_SURFACE,
+ "image/webp",
+ NULL);
+ /*gth_main_register_type ("image-saver", GTH_TYPE_IMAGE_SAVER_WEBP);*/
+#endif
+
gth_hook_add_callback ("dlg-preferences-construct", 30, G_CALLBACK (ci__dlg_preferences_construct_cb), NULL);
gth_hook_add_callback ("dlg-preferences-apply", 10, G_CALLBACK (ci__dlg_preferences_apply_cb), NULL);
}
diff --git a/extensions/image_viewer/gth-metadata-provider-image.c b/extensions/image_viewer/gth-metadata-provider-image.c
index b03217c..411443e 100644
--- a/extensions/image_viewer/gth-metadata-provider-image.c
+++ b/extensions/image_viewer/gth-metadata-provider-image.c
@@ -27,10 +27,13 @@
#if HAVE_LIBJPEG
#include <extensions/jpeg_utils/jpeg-info.h>
#endif /* HAVE_LIBJPEG */
+#if HAVE_LIBWEBP
+#include <webp/decode.h>
+#endif /* HAVE_LIBWEBP */
#include "gth-metadata-provider-image.h"
-#define BUFFER_SIZE 32
+#define BUFFER_SIZE 1024
G_DEFINE_TYPE (GthMetadataProviderImage, gth_metadata_provider_image, GTH_TYPE_METADATA_PROVIDER)
@@ -104,10 +107,9 @@ gth_metadata_provider_image_read (GthMetadataProvider *self,
width = (buffer[16] << 24) + (buffer[17] << 16) + (buffer[18] << 8) + buffer[19];
height = (buffer[20] << 24) + (buffer[21] << 16) + (buffer[22] << 8) + buffer[23];
-
- format_recognized = TRUE;
- description = "PNG";
+ description = _("PNG");
mime_type = "image/png";
+ format_recognized = TRUE;
}
#if HAVE_LIBJPEG
@@ -135,9 +137,9 @@ gth_metadata_provider_image_read (GthMetadataProvider *self,
cancellable,
NULL))
{
- format_recognized = TRUE;
- description = "JPEG";
+ description = _("JPEG");
mime_type = "image/jpeg";
+ format_recognized = TRUE;
if ((orientation == GTH_TRANSFORM_ROTATE_90)
|| (orientation == GTH_TRANSFORM_ROTATE_270)
@@ -151,6 +153,23 @@ gth_metadata_provider_image_read (GthMetadataProvider *self,
}
}
#endif /* HAVE_LIBJPEG */
+
+#if HAVE_LIBWEBP
+ else if ((size > 15) && (memcmp (buffer + 8, "WEBPVP8", 7) == 0)) {
+ WebPDecoderConfig config;
+
+ if (WebPInitDecoderConfig (&config)) {
+ if (WebPGetFeatures (buffer, buffer_size, &config.input) == VP8_STATUS_OK) {
+ width = config.input.width;
+ height = config.input.height;
+ description = _("WebP");
+ mime_type = "image/webp";
+ format_recognized = TRUE;
+ }
+ WebPFreeDecBuffer (&config.output);
+ }
+ }
+#endif /* HAVE_LIBWEBP */
}
g_free (buffer);
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 224a587..79aa888 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -274,6 +274,7 @@ gthumb_LDADD = \
$(LIBSOUP_LIBS) \
$(LIBCHAMPLAIN_LIBS) \
$(LIBRSVG_LIBS) \
+ $(LIBWEBP_LIBS) \
$(NULL)
if RUN_IN_PLACE
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index a25a3a7..c25df62 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -2799,6 +2799,20 @@ _g_file_info_swap_attributes (GFileInfo *info,
}
+const char *
+_g_content_type_guess_from_name (const char *filename)
+{
+#if WEBP_IS_UNKNOWN_TO_GLIB
+ const char *ext;
+
+ ext = _g_uri_get_file_extension (filename);
+ if (g_strcmp0 (ext, ".webp") == 0)
+ return "image/webp";
+#endif
+ return g_content_type_guess (filename, NULL, 0, NULL);
+}
+
+
gboolean
_g_content_type_is_a (const char *type,
const char *supertype)
@@ -2848,12 +2862,13 @@ get_mime_type_from_magic_numbers (void *buffer,
const char * const mime_type;
}
magic_ids [] = {
- /* magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
+ /* some magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
{ 0, 8, "\x89PNG\x0d\x0a\x1a\x0a", "image/png" },
{ 0, 4, "MM\x00\x2a", "image/tiff" },
{ 0, 4, "II\x2a\x00", "image/tiff" },
{ 0, 4, "GIF8", "image/gif" },
- { 0, 2, "\xff\xd8", "image/jpeg" },
+ { 0, 3, "\xff\xd8\xff", "image/jpeg" },
+ { 8, 7, "WEBPVP8", "image/webp" }
};
int i;
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index c647d0f..f870863 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -307,6 +307,7 @@ gboolean _g_file_attributes_matches_any_v (const char *attributes,
void _g_file_info_swap_attributes (GFileInfo *info,
const char *attr1,
const char *attr2);
+const char * _g_content_type_guess_from_name (const char *filename);
gboolean _g_content_type_is_a (const char *type,
const char *supertype);
const char * _g_content_type_get_from_stream (GInputStream *istream,
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 1f8b782..78704bd 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -223,7 +223,7 @@ gth_file_data_get_mime_type (GthFileData *self)
if (filename == NULL)
return NULL;
- content_type = g_content_type_guess (filename, NULL, 0, NULL);
+ content_type = _g_content_type_guess_from_name (filename);
g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, content_type);
g_free (filename);
@@ -267,7 +267,7 @@ gth_file_data_get_mime_type_from_content (GthFileData *self,
content_type = _g_content_type_get_from_stream (istream, cancellable, &error);
if ((content_type == NULL) || (strcmp (content_type, "application/xml") == 0))
- content_type = g_content_type_guess (filename, NULL, 0, NULL);
+ content_type = _g_content_type_guess_from_name (filename);
g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, content_type);
diff --git a/gthumb/gth-metadata-provider.c b/gthumb/gth-metadata-provider.c
index 5c06085..833c8cf 100644
--- a/gthumb/gth-metadata-provider.c
+++ b/gthumb/gth-metadata-provider.c
@@ -177,6 +177,23 @@ _g_query_metadata_async_thread (GSimpleAsyncResult *result,
break;
}
+#if WEBP_IS_UNKNOWN_TO_GLIB
+ if (_g_file_attributes_matches_any_v (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
+ qmd->attributes_v))
+ {
+ char *uri;
+ const char *ext;
+
+ uri = g_file_get_uri (file_data->file);
+ ext = _g_uri_get_file_extension (uri);
+ if (g_strcmp0 (ext, ".webp") == 0)
+ gth_file_data_set_mime_type (file_data, "image/webp");
+
+ g_free (uri);
+ }
+#endif
+
for (scan_providers = providers; scan_providers; scan_providers = scan_providers->next) {
GthMetadataProvider *metadata_provider = scan_providers->data;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]