aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-12-12 21:30:54 +0100
committerPřemysl Eric Janouch <p@janouch.name>2021-12-12 21:31:30 +0100
commit006e547deba1e952d9de1a52d511edf9e6a8f07c (patch)
tree5031fb9b9dcda76d4a29b26f4f3a8a26b294efc7
parentcaca14036c0b26df6eef4cdaef9cb7811545d52b (diff)
downloadfiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.tar.gz
fiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.tar.xz
fiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.zip
Read out Exif and ICC profiles from WebP
-rw-r--r--fastiv-io.c34
-rw-r--r--meson.build2
2 files changed, 33 insertions, 3 deletions
diff --git a/fastiv-io.c b/fastiv-io.c
index e637d1d..67eeb96 100644
--- a/fastiv-io.c
+++ b/fastiv-io.c
@@ -35,6 +35,7 @@
#endif // HAVE_XCURSOR
#ifdef HAVE_LIBWEBP
#include <webp/decode.h>
+#include <webp/demux.h>
#endif // HAVE_LIBWEBP
#ifdef HAVE_LIBHEIF
#include <libheif/heif.h>
@@ -1116,7 +1117,7 @@ open_xcursor(const gchar *data, gsize len, GError **error)
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
static cairo_surface_t *
-open_libwebp(const gchar *data, gsize len, GError **error)
+open_libwebp(const gchar *data, gsize len, const gchar *path, GError **error)
{
// It is wholly zero-initialized by libwebp.
WebPDecoderConfig config = {};
@@ -1132,6 +1133,7 @@ open_libwebp(const gchar *data, gsize len, GError **error)
return NULL;
}
+ // TODO(p): Support animations through WebPAnimDecoder (has_animation).
cairo_surface_t *result = NULL;
cairo_surface_t *surface = cairo_image_surface_create(
@@ -1162,7 +1164,33 @@ open_libwebp(const gchar *data, gsize len, GError **error)
goto fail;
}
- // TODO(p): Extract metadata, support animations (has_animation).
+ // Of course everything has to use a different abstraction.
+ WebPData wd = {.bytes = (const uint8_t *) data, .size = len};
+ WebPDemuxer *demux = WebPDemux(&wd);
+ if (!demux) {
+ g_warning("%s: %s", path, "demux failure");
+ goto fail_demux;
+ }
+
+ uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+ WebPChunkIterator chunk_iter;
+ if ((flags & ICCP_FLAG) &&
+ WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
+ cairo_surface_set_user_data(surface, &fastiv_io_key_icc,
+ g_bytes_new(chunk_iter.chunk.bytes, chunk_iter.chunk.size),
+ (cairo_destroy_func_t) g_bytes_unref);
+ }
+ if ((flags & EXIF_FLAG) &&
+ WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
+ cairo_surface_set_user_data(surface, &fastiv_io_key_exif,
+ g_bytes_new(chunk_iter.chunk.bytes, chunk_iter.chunk.size),
+ (cairo_destroy_func_t) g_bytes_unref);
+ }
+
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ WebPDemuxDelete(demux);
+
+fail_demux:
result = surface;
fail:
@@ -1748,7 +1776,7 @@ fastiv_io_open_from_data(const char *data, size_t len, const gchar *path,
}
#endif // HAVE_XCURSOR --------------------------------------------------------
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
- if ((surface = open_libwebp(data, len, error)))
+ if ((surface = open_libwebp(data, len, path, error)))
break;
if (error) {
g_debug("%s", (*error)->message);
diff --git a/meson.build b/meson.build
index 5538323..7b8cb20 100644
--- a/meson.build
+++ b/meson.build
@@ -18,6 +18,7 @@ libraw = dependency('libraw', required : get_option('libraw'))
librsvg = dependency('librsvg-2.0', required : get_option('librsvg'))
xcursor = dependency('xcursor', required : get_option('xcursor'))
libwebp = dependency('libwebp', required : get_option('libwebp'))
+libwebpdemux = dependency('libwebpdemux', required : get_option('libwebp'))
libwebpdecoder = dependency('libwebpdecoder', required : get_option('libwebp'))
libheif = dependency('libheif', required : get_option('libheif'))
libtiff = dependency('libtiff-4', required : get_option('libtiff'))
@@ -32,6 +33,7 @@ dependencies = [
librsvg,
xcursor,
libwebp,
+ libwebpdemux,
libwebpdecoder,
libheif,
libtiff,