diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2021-12-12 21:30:54 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2021-12-12 21:31:30 +0100 |
commit | 006e547deba1e952d9de1a52d511edf9e6a8f07c (patch) | |
tree | 5031fb9b9dcda76d4a29b26f4f3a8a26b294efc7 | |
parent | caca14036c0b26df6eef4cdaef9cb7811545d52b (diff) | |
download | fiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.tar.gz fiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.tar.xz fiv-006e547deba1e952d9de1a52d511edf9e6a8f07c.zip |
Read out Exif and ICC profiles from WebP
-rw-r--r-- | fastiv-io.c | 34 | ||||
-rw-r--r-- | meson.build | 2 |
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, |