summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-02-17 11:50:39 +0000
committerVincent Sanders <vince@kyllikki.org>2019-02-17 11:50:39 +0000
commit160d15b45b45136d273b16fefb59d9071dd77d6d (patch)
tree7be89e0aad92e71c0fd5094132918309fadc31b8
parent54371c28f07e638694ad2148e8900e1bae71e3d4 (diff)
downloadnetsurf-vince/webp.tar.gz
netsurf-vince/webp.tar.bz2
add webp image handlervince/webp
-rw-r--r--Makefile2
-rw-r--r--Makefile.defaults4
-rw-r--r--content/handlers/image/Makefile4
-rw-r--r--content/handlers/image/image.c7
-rw-r--r--content/handlers/image/jpeg.c8
-rw-r--r--content/handlers/image/webp.c232
-rw-r--r--content/handlers/image/webp.h29
7 files changed, 283 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index f86042897..0d4f3ae7d 100644
--- a/Makefile
+++ b/Makefile
@@ -535,6 +535,7 @@ LDFLAGS += -lz
# Optional libraries with pkgconfig
# define additional CFLAGS and LDFLAGS requirements for pkg-configed libs
+NETSURF_FEATURE_WEBP_CFLAGS := -DWITH_WEBP
NETSURF_FEATURE_PNG_CFLAGS := -DWITH_PNG
NETSURF_FEATURE_BMP_CFLAGS := -DWITH_BMP
NETSURF_FEATURE_GIF_CFLAGS := -DWITH_GIF
@@ -558,6 +559,7 @@ else
endif
$(eval $(call pkg_config_find_and_add_enabled,OPENSSL,openssl,OpenSSL))
+$(eval $(call pkg_config_find_and_add_enabled,WEBP,libwebp,WEBP))
$(eval $(call pkg_config_find_and_add_enabled,PNG,libpng,PNG))
$(eval $(call pkg_config_find_and_add_enabled,BMP,libnsbmp,BMP))
$(eval $(call pkg_config_find_and_add_enabled,GIF,libnsgif,GIF))
diff --git a/Makefile.defaults b/Makefile.defaults
index 51090109e..cebd41cf8 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -59,6 +59,10 @@ NETSURF_USE_PNG := YES
# Valid options: YES, NO
NETSURF_USE_VIDEO := NO
+# Enable NetSurf's use of libwebp for displaying WEBPs.
+# Valid options: YES, NO, AUTO
+NETSURF_USE_WEBP := AUTO
+
# Enable NetSurf's use of duktape for javascript
# Valid options: YES, NO
NETSURF_USE_DUKTAPE := YES
diff --git a/content/handlers/image/Makefile b/content/handlers/image/Makefile
index 541cd2cf9..1c27f74d7 100644
--- a/content/handlers/image/Makefile
+++ b/content/handlers/image/Makefile
@@ -3,13 +3,15 @@
# S_IMAGE are sources related to image management
S_IMAGE_YES := image.c image_cache.c
S_IMAGE_NO :=
-S_IMAGE_$(NETSURF_USE_BMP) += bmp.c ico.c
+S_IMAGE_$(NETSURF_USE_BMP) += bmp.c
S_IMAGE_$(NETSURF_USE_GIF) += gif.c
+S_IMAGE_$(NETSURF_USE_BMP) += ico.c
S_IMAGE_$(NETSURF_USE_JPEG) += jpeg.c
S_IMAGE_$(NETSURF_USE_ROSPRITE) += nssprite.c
S_IMAGE_$(NETSURF_USE_PNG) += png.c
S_IMAGE_$(NETSURF_USE_NSSVG) += svg.c
S_IMAGE_$(NETSURF_USE_RSVG) += rsvg.c
S_IMAGE_$(NETSURF_USE_VIDEO) += video.c
+S_IMAGE_$(NETSURF_USE_WEBP) += webp.c
S_IMAGE := $(S_IMAGE_YES)
diff --git a/content/handlers/image/image.c b/content/handlers/image/image.c
index 675fdd691..4eb366e0b 100644
--- a/content/handlers/image/image.c
+++ b/content/handlers/image/image.c
@@ -35,6 +35,7 @@
#include "image/png.h"
#include "image/rsvg.h"
#include "image/svg.h"
+#include "image/webp.h"
#include "image/image.h"
/**
@@ -94,6 +95,12 @@ nserror image_init(void)
return error;
#endif
+#ifdef WITH_WEBP
+ error = nswebp_init();
+ if (error != NSERROR_OK)
+ return error;
+#endif
+
return error;
}
diff --git a/content/handlers/image/jpeg.c b/content/handlers/image/jpeg.c
index 123a0bf70..e2f5f8f26 100644
--- a/content/handlers/image/jpeg.c
+++ b/content/handlers/image/jpeg.c
@@ -17,8 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Content for image/jpeg (implementation).
+/**
+ * \file
+ * implementation of content handling for image/jpeg
*
* This implementation uses the IJG JPEG library.
*/
@@ -161,6 +162,9 @@ static void nsjpeg_error_exit(j_common_ptr cinfo)
longjmp(*setjmp_buffer, 1);
}
+/**
+ * create a bitmap from jpeg content.
+ */
static struct bitmap *
jpeg_cache_convert(struct content *c)
{
diff --git a/content/handlers/image/webp.c b/content/handlers/image/webp.c
new file mode 100644
index 000000000..66a86c9f4
--- /dev/null
+++ b/content/handlers/image/webp.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2019 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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/>.
+ */
+
+/**
+ * \file
+ * implementation of content handling for image/webp
+ *
+ * This implementation uses the google webp library.
+ * Image cache handling is performed by the generic NetSurf handler.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#include <webp/decode.h>
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "netsurf/bitmap.h"
+#include "content/llcache.h"
+#include "content/content_protected.h"
+#include "desktop/gui_internal.h"
+
+#include "image/image_cache.h"
+
+#include "webp.h"
+
+/**
+ * Content create entry point.
+ *
+ * create a content object for the webp
+ */
+static nserror
+webp_create(const content_handler *handler,
+ lwc_string *imime_type,
+ const struct http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset,
+ bool quirks,
+ struct content **c)
+{
+ struct content *webp_c; /* webp content object */
+ nserror res;
+
+ webp_c = calloc(1, sizeof(struct content));
+ if (webp_c == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = content__init(webp_c,
+ handler,
+ imime_type,
+ params,
+ llcache,
+ fallback_charset,
+ quirks);
+ if (res != NSERROR_OK) {
+ free(webp_c);
+ return res;
+ }
+
+ *c = webp_c;
+
+ return NSERROR_OK;
+}
+
+/**
+ * create a bitmap from webp content.
+ */
+static struct bitmap *
+webp_cache_convert(struct content *c)
+{
+ const uint8_t *source_data; /* webp source data */
+ unsigned long source_size; /* length of webp source data */
+ VP8StatusCode webpres;
+ WebPBitstreamFeatures webpfeatures;
+ unsigned int bmap_flags;
+ uint8_t *pixels = NULL;
+ uint8_t *decoded;
+ size_t rowstride;
+ struct bitmap *bitmap = NULL;
+
+ source_data = (uint8_t *)content__get_source_data(c, &source_size);
+
+ webpres = WebPGetFeatures(source_data, source_size, &webpfeatures);
+
+ if (webpres != VP8_STATUS_OK) {
+ return NULL;
+ }
+
+ if (webpfeatures.has_alpha == 0) {
+ bmap_flags = BITMAP_NEW | BITMAP_OPAQUE;
+ } else {
+ bmap_flags = BITMAP_NEW;
+ }
+
+ /* create bitmap */
+ bitmap = guit->bitmap->create(webpfeatures.width,
+ webpfeatures.height,
+ bmap_flags);
+ if (bitmap == NULL) {
+ /* empty bitmap could not be created */
+ return NULL;
+ }
+
+ pixels = guit->bitmap->get_buffer(bitmap);
+ if (pixels == NULL) {
+ /* bitmap with no buffer available */
+ guit->bitmap->destroy(bitmap);
+ return NULL;
+ }
+
+ rowstride = guit->bitmap->get_rowstride(bitmap);
+
+ decoded = WebPDecodeBGRAInto(source_data,
+ source_size,
+ pixels,
+ webpfeatures.width * webpfeatures.height * 4,
+ rowstride);
+ if (decoded == NULL) {
+ /* decode failed */
+ guit->bitmap->destroy(bitmap);
+ return NULL;
+ }
+
+ return bitmap;
+}
+
+/**
+ * Convert the webp source data content.
+ *
+ * This ensures there is valid webp source data in the content object
+ * and then adds it to the image cache ready to be converted on
+ * demand.
+ *
+ * \param c The webp content object
+ * \return true on successful processing of teh webp content else false
+ */
+static bool webp_convert(struct content *c)
+{
+ int res;
+ unsigned long data_size;
+ const uint8_t* data;
+ int width;
+ int height;
+
+ data = (uint8_t *)content__get_source_data(c, &data_size);
+
+ res = WebPGetInfo(data, data_size, &width, &height);
+ if (res == 0) {
+ NSLOG(netsurf, INFO, "WebPGetInfo failed:%p", c);
+ return false;
+ }
+
+ c->width = width;
+ c->height = height;
+ c->size = c->width * c->height * 4;
+
+ image_cache_add(c, NULL, webp_cache_convert);
+
+ content_set_ready(c);
+ content_set_done(c);
+
+ return true;
+}
+
+/**
+ * Clone content.
+ */
+static nserror webp_clone(const struct content *old, struct content **new_c)
+{
+ struct content *webp_c; /* cloned webp content */
+ nserror res;
+
+ webp_c = calloc(1, sizeof(struct content));
+ if (webp_c == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = content__clone(old, webp_c);
+ if (res != NSERROR_OK) {
+ content_destroy(webp_c);
+ return res;
+ }
+
+ /* re-convert if the content is ready */
+ if ((old->status == CONTENT_STATUS_READY) ||
+ (old->status == CONTENT_STATUS_DONE)) {
+ if (webp_convert(webp_c) == false) {
+ content_destroy(webp_c);
+ return NSERROR_CLONE_FAILED;
+ }
+ }
+
+ *new_c = webp_c;
+
+ return NSERROR_OK;
+}
+
+static const content_handler webp_content_handler = {
+ .create = webp_create,
+ .data_complete = webp_convert,
+ .destroy = image_cache_destroy,
+ .redraw = image_cache_redraw,
+ .clone = webp_clone,
+ .get_internal = image_cache_get_internal,
+ .type = image_cache_content_type,
+ .no_share = false,
+};
+
+static const char *webp_types[] = {
+ "image/webp"
+};
+
+CONTENT_FACTORY_REGISTER_TYPES(nswebp, webp_types, webp_content_handler);
diff --git a/content/handlers/image/webp.h b/content/handlers/image/webp.h
new file mode 100644
index 000000000..b219f2576
--- /dev/null
+++ b/content/handlers/image/webp.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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/>.
+ */
+
+/**
+ * \file
+ * Interface to image/webp content handlers
+ */
+
+#ifndef _NETSURF_IMAGE_WEBP_H_
+#define _NETSURF_IMAGE_WEBP_H_
+
+nserror nswebp_init(void);
+
+#endif