Read out Exif and ICC profiles from WebP
This commit is contained in:
parent
caca14036c
commit
006e547deb
34
fastiv-io.c
34
fastiv-io.c
@ -35,6 +35,7 @@
|
|||||||
#endif // HAVE_XCURSOR
|
#endif // HAVE_XCURSOR
|
||||||
#ifdef HAVE_LIBWEBP
|
#ifdef HAVE_LIBWEBP
|
||||||
#include <webp/decode.h>
|
#include <webp/decode.h>
|
||||||
|
#include <webp/demux.h>
|
||||||
#endif // HAVE_LIBWEBP
|
#endif // HAVE_LIBWEBP
|
||||||
#ifdef HAVE_LIBHEIF
|
#ifdef HAVE_LIBHEIF
|
||||||
#include <libheif/heif.h>
|
#include <libheif/heif.h>
|
||||||
@ -1116,7 +1117,7 @@ open_xcursor(const gchar *data, gsize len, GError **error)
|
|||||||
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
|
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
|
||||||
|
|
||||||
static cairo_surface_t *
|
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.
|
// It is wholly zero-initialized by libwebp.
|
||||||
WebPDecoderConfig config = {};
|
WebPDecoderConfig config = {};
|
||||||
@ -1132,6 +1133,7 @@ open_libwebp(const gchar *data, gsize len, GError **error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(p): Support animations through WebPAnimDecoder (has_animation).
|
||||||
cairo_surface_t *result = NULL;
|
cairo_surface_t *result = NULL;
|
||||||
|
|
||||||
cairo_surface_t *surface = cairo_image_surface_create(
|
cairo_surface_t *surface = cairo_image_surface_create(
|
||||||
@ -1162,7 +1164,33 @@ open_libwebp(const gchar *data, gsize len, GError **error)
|
|||||||
goto fail;
|
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;
|
result = surface;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -1748,7 +1776,7 @@ fastiv_io_open_from_data(const char *data, size_t len, const gchar *path,
|
|||||||
}
|
}
|
||||||
#endif // HAVE_XCURSOR --------------------------------------------------------
|
#endif // HAVE_XCURSOR --------------------------------------------------------
|
||||||
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
|
#ifdef HAVE_LIBWEBP //---------------------------------------------------------
|
||||||
if ((surface = open_libwebp(data, len, error)))
|
if ((surface = open_libwebp(data, len, path, error)))
|
||||||
break;
|
break;
|
||||||
if (error) {
|
if (error) {
|
||||||
g_debug("%s", (*error)->message);
|
g_debug("%s", (*error)->message);
|
||||||
|
@ -18,6 +18,7 @@ libraw = dependency('libraw', required : get_option('libraw'))
|
|||||||
librsvg = dependency('librsvg-2.0', required : get_option('librsvg'))
|
librsvg = dependency('librsvg-2.0', required : get_option('librsvg'))
|
||||||
xcursor = dependency('xcursor', required : get_option('xcursor'))
|
xcursor = dependency('xcursor', required : get_option('xcursor'))
|
||||||
libwebp = dependency('libwebp', required : get_option('libwebp'))
|
libwebp = dependency('libwebp', required : get_option('libwebp'))
|
||||||
|
libwebpdemux = dependency('libwebpdemux', required : get_option('libwebp'))
|
||||||
libwebpdecoder = dependency('libwebpdecoder', required : get_option('libwebp'))
|
libwebpdecoder = dependency('libwebpdecoder', required : get_option('libwebp'))
|
||||||
libheif = dependency('libheif', required : get_option('libheif'))
|
libheif = dependency('libheif', required : get_option('libheif'))
|
||||||
libtiff = dependency('libtiff-4', required : get_option('libtiff'))
|
libtiff = dependency('libtiff-4', required : get_option('libtiff'))
|
||||||
@ -32,6 +33,7 @@ dependencies = [
|
|||||||
librsvg,
|
librsvg,
|
||||||
xcursor,
|
xcursor,
|
||||||
libwebp,
|
libwebp,
|
||||||
|
libwebpdemux,
|
||||||
libwebpdecoder,
|
libwebpdecoder,
|
||||||
libheif,
|
libheif,
|
||||||
libtiff,
|
libtiff,
|
||||||
|
Loading…
Reference in New Issue
Block a user