diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2021-12-11 18:25:25 +0100 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2021-12-12 19:15:34 +0100 | 
| commit | caca14036c0b26df6eef4cdaef9cb7811545d52b (patch) | |
| tree | 5e5aba2b9f8c24646a69965582545a90b06198b2 | |
| parent | b868e76a1573c4f112477c8b38fbe1e82685ac88 (diff) | |
| download | fiv-caca14036c0b26df6eef4cdaef9cb7811545d52b.tar.gz fiv-caca14036c0b26df6eef4cdaef9cb7811545d52b.tar.xz fiv-caca14036c0b26df6eef4cdaef9cb7811545d52b.zip  | |
Add preliminary direct support for WebP
| -rw-r--r-- | README.adoc | 5 | ||||
| -rw-r--r-- | fastiv-io.c | 72 | ||||
| -rw-r--r-- | meson.build | 5 | ||||
| -rw-r--r-- | meson_options.txt | 2 | 
4 files changed, 82 insertions, 2 deletions
diff --git a/README.adoc b/README.adoc index 33691d8..ceab31c 100644 --- a/README.adoc +++ b/README.adoc @@ -2,7 +2,8 @@ fastiv  ======  'fastiv' is a fast image viewer, supporting BMP, PNG, GIF, JPEG, and optionally -raw photos, HEIC, AVIF, SVG, X11 cursors and TIFF, or whatever gdk-pixbuf loads. +raw photos, HEIC, AVIF, WebP, SVG, X11 cursors and TIFF, or whatever gdk-pixbuf +loads.  It still has some road to go, but it's already become quite usable,  and it has received basic polishing. @@ -25,7 +26,7 @@ Building and Running  Build dependencies: Meson, pkg-config +  Runtime dependencies: gtk+-3.0, glib>=2.64, pixman-1, shared-mime-info,  spng>=0.7.0, libturbojpeg + -Optional dependencies: LibRaw, librsvg-2.0, xcursor, libheif, libtiff, +Optional dependencies: LibRaw, librsvg-2.0, xcursor, libwebp, libheif, libtiff,  gdk-pixbuf-2.0   $ git clone --recursive https://git.janouch.name/p/fastiv.git diff --git a/fastiv-io.c b/fastiv-io.c index 87e26b3..e637d1d 100644 --- a/fastiv-io.c +++ b/fastiv-io.c @@ -33,6 +33,9 @@  #ifdef HAVE_XCURSOR  #include <X11/Xcursor/Xcursor.h>  #endif  // HAVE_XCURSOR +#ifdef HAVE_LIBWEBP +#include <webp/decode.h> +#endif  // HAVE_LIBWEBP  #ifdef HAVE_LIBHEIF  #include <libheif/heif.h>  #endif  // HAVE_LIBHEIF @@ -1110,6 +1113,67 @@ open_xcursor(const gchar *data, gsize len, GError **error)  }  #endif  // HAVE_XCURSOR -------------------------------------------------------- +#ifdef HAVE_LIBWEBP  //--------------------------------------------------------- + +static cairo_surface_t * +open_libwebp(const gchar *data, gsize len, GError **error) +{ +	// It is wholly zero-initialized by libwebp. +	WebPDecoderConfig config = {}; +	if (!WebPInitDecoderConfig(&config)) { +		set_error(error, "libwebp version mismatch"); +		return NULL; +	} + +	// TODO(p): Differentiate between a bad WebP, and not a WebP. +	VP8StatusCode err = 0; +	if ((err = WebPGetFeatures((const uint8_t *) data, len, &config.input))) { +		set_error(error, "WebP decoding error"); +		return NULL; +	} + +	cairo_surface_t *result = NULL; + +	cairo_surface_t *surface = cairo_image_surface_create( +		config.input.has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, +		config.input.width, config.input.height); +	cairo_status_t surface_status = cairo_surface_status(surface); +	if (surface_status != CAIRO_STATUS_SUCCESS) { +		set_error(error, cairo_status_to_string(surface_status)); +		goto fail; +	} + +	config.options.use_threads = true; + +	config.output.width = config.input.width; +	config.output.height = config.input.height; +	config.output.is_external_memory = true; +	config.output.u.RGBA.rgba = cairo_image_surface_get_data(surface); +	config.output.u.RGBA.stride = cairo_image_surface_get_stride(surface); +	config.output.u.RGBA.size = +		config.output.u.RGBA.stride * cairo_image_surface_get_height(surface); +	if (G_BYTE_ORDER == G_LITTLE_ENDIAN) +		config.output.colorspace = MODE_bgrA; +	else +		config.output.colorspace = MODE_Argb; + +	if ((err = WebPDecode((const uint8_t *) data, len, &config))) { +		set_error(error, "WebP decoding error"); +		goto fail; +	} + +	// TODO(p): Extract metadata, support animations (has_animation). +	result = surface; + +fail: +	if (!result) +		cairo_surface_destroy(surface); + +	WebPFreeDecBuffer(&config.output); +	return result; +} + +#endif  // HAVE_LIBWEBP --------------------------------------------------------  #ifdef HAVE_LIBHEIF  //---------------------------------------------------------  static cairo_surface_t * @@ -1683,6 +1747,14 @@ fastiv_io_open_from_data(const char *data, size_t len, const gchar *path,  			g_clear_error(error);  		}  #endif  // HAVE_XCURSOR -------------------------------------------------------- +#ifdef HAVE_LIBWEBP  //--------------------------------------------------------- +		if ((surface = open_libwebp(data, len, error))) +			break; +		if (error) { +			g_debug("%s", (*error)->message); +			g_clear_error(error); +		} +#endif  // HAVE_LIBWEBP --------------------------------------------------------  #ifdef HAVE_LIBHEIF  //---------------------------------------------------------  		if ((surface = open_libheif(data, len, path, error)))  			break; diff --git a/meson.build b/meson.build index bbd0cc5..5538323 100644 --- a/meson.build +++ b/meson.build @@ -17,6 +17,8 @@ endif  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')) +libwebpdecoder = dependency('libwebpdecoder', required : get_option('libwebp'))  libheif = dependency('libheif', required : get_option('libheif'))  libtiff = dependency('libtiff-4', required : get_option('libtiff'))  gdkpixbuf = dependency('gdk-pixbuf-2.0', required : get_option('gdk-pixbuf')) @@ -29,6 +31,8 @@ dependencies = [  	libraw,  	librsvg,  	xcursor, +	libwebp, +	libwebpdecoder,  	libheif,  	libtiff,  	gdkpixbuf, @@ -41,6 +45,7 @@ conf.set_quoted('PROJECT_VERSION', meson.project_version())  conf.set('HAVE_LIBRAW', libraw.found())  conf.set('HAVE_LIBRSVG', librsvg.found())  conf.set('HAVE_XCURSOR', xcursor.found()) +conf.set('HAVE_LIBWEBP', libwebp.found())  conf.set('HAVE_LIBHEIF', libheif.found())  conf.set('HAVE_LIBTIFF', libtiff.found())  conf.set('HAVE_GDKPIXBUF', gdkpixbuf.found()) diff --git a/meson_options.txt b/meson_options.txt index f428622..3edd0e1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,6 +4,8 @@ option('librsvg', type : 'feature', value : 'auto',  	description : 'Build with SVG support, requires librsvg')  option('xcursor', type : 'feature', value : 'auto',  	description : 'Build with Xcursor support, requires libXcursor') +option('libwebp', type : 'feature', value : 'auto', +	description : 'Build with WEBP support, requires libwebp')  option('libheif', type : 'feature', value : 'auto',  	description : 'Build with HEIF/AVIF support, requires libheif')  option('libtiff', type : 'feature', value : 'auto',  | 
