From: Igor Murzov <e-mail@date.by>
authorIgor Murzov <e-mail@date.by>
Mon, 3 Sep 2012 06:22:59 +0000 (06:22 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Mon, 3 Sep 2012 06:22:59 +0000 (06:22 +0000)
Subject: [E-devel] [PATCH][RESEND][Evas] WebP image loader

This patch adds a WebP image loader to Evas. No saver,
no animation support for now, just loader. Tested with
the libwebp-0.2.0 only, but should work fine with older
versions.

SVN revision: 75951

15 files changed:
legacy/evas/AUTHORS
legacy/evas/ChangeLog
legacy/evas/NEWS
legacy/evas/README
legacy/evas/configure.ac
legacy/evas/m4/evas_check_loader.m4
legacy/evas/src/bin/evas_cserve2_slave.c
legacy/evas/src/bin/loaders/Makefile.am
legacy/evas/src/bin/loaders/webp/Makefile.am [new file with mode: 0644]
legacy/evas/src/bin/loaders/webp/evas_image_load_webp.c [new file with mode: 0644]
legacy/evas/src/lib/engines/common/evas_image_load.c
legacy/evas/src/lib/file/evas_module.c
legacy/evas/src/modules/loaders/Makefile.am
legacy/evas/src/modules/loaders/webp/Makefile.am [new file with mode: 0644]
legacy/evas/src/modules/loaders/webp/evas_image_load_webp.c [new file with mode: 0644]

index ae614e5..f8c2a51 100644 (file)
@@ -37,3 +37,4 @@ Jérôme Pinot <ngc891@gmail.com>
 Rafael Antognolli <antognolli@profusion.mobi>
 Daniel Zaoui <daniel.zaoui@samsung.com>
 Christophe Sadoine <chris@indefini.org>
+Igor Murzov <e-mail@date.by>
index 2e9c5c9..dfce0a1 100644 (file)
 
        * Fix seg fault in the esvg loader, latest code is required, and
         enable it on Windows.
+
+2012-09-03  Igor Murzov
+
+       * Add WEBP loader module and cserve2 binary loader patch.
index 27c0875..6b96648 100644 (file)
@@ -3,6 +3,10 @@ Evas 1.8.0
 Changes since Evas 1.7.0:
 -------------------------
 
+Additions:
+
+   * WEBP image loader support.
+
 Improvements:
 
    * Function to rotate an evas map with a quaternion: evas_map_util_quat_rotate().
index 5e0b0bc..7660890 100644 (file)
@@ -527,6 +527,9 @@ egueb
 
 this loader uses libtiff to load tiff image files
 
+--enable-image-loader-webp[=static]
+
+this loader uses libwebp to load webp image files
 
 --enable-image-loader-xpm[=static]
 
index 30f5785..8dfd9bb 100644 (file)
@@ -126,6 +126,7 @@ want_evas_image_loader_xpm="yes"
 want_evas_image_loader_bmp="yes"
 want_evas_image_loader_tga="yes"
 want_evas_image_loader_wbmp="yes"
+want_evas_image_loader_webp="yes"
 want_evas_image_loader_ico="yes"
 want_evas_image_loader_psd="yes"
 want_evas_image_loader_generic="yes"
@@ -1058,6 +1059,8 @@ EVAS_CHECK_IMAGE_LOADER([TGA], [${want_evas_image_loader_tga}])
 
 EVAS_CHECK_IMAGE_LOADER([WBMP], [${want_evas_image_loader_wbmp}])
 
+EVAS_CHECK_IMAGE_LOADER([WEBP], [${want_evas_image_loader_webp}])
+
 EVAS_CHECK_IMAGE_LOADER([ICO], [${want_evas_image_loader_ico}])
 
 EVAS_CHECK_IMAGE_LOADER([PSD], [${want_evas_image_loader_psd}])
@@ -1845,6 +1848,7 @@ src/bin/loaders/ico/Makefile
 src/bin/loaders/tga/Makefile
 src/bin/loaders/pmaps/Makefile
 src/bin/loaders/wbmp/Makefile
+src/bin/loaders/webp/Makefile
 src/bin/loaders/psd/Makefile
 src/lib/Makefile
 src/lib/canvas/Makefile
@@ -1900,6 +1904,7 @@ src/modules/loaders/tga/Makefile
 src/modules/loaders/svg/Makefile
 src/modules/loaders/pmaps/Makefile
 src/modules/loaders/wbmp/Makefile
+src/modules/loaders/webp/Makefile
 src/modules/loaders/psd/Makefile
 src/modules/loaders/generic/Makefile
 src/modules/savers/Makefile
@@ -1994,6 +1999,7 @@ echo "  SVG.....................: $have_evas_image_loader_svg"
 echo "  TGA.....................: $have_evas_image_loader_tga"
 echo "  TIFF....................: $have_evas_image_loader_tiff"
 echo "  WBMP....................: $have_evas_image_loader_wbmp"
+echo "  WEBP....................: $have_evas_image_loader_webp"
 echo "  XPM.....................: $have_evas_image_loader_xpm"
 echo
 echo "Font Sourcing Systems:"
index cf4924e..0130484 100644 (file)
@@ -429,6 +429,38 @@ fi
 
 ])
 
+dnl use: EVAS_CHECK_LOADER_DEP_WEBP(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_LOADER_DEP_WEBP],
+[
+
+have_dep="no"
+evas_image_loader_[]$1[]_cflags=""
+evas_image_loader_[]$1[]_libs=""
+
+AC_CHECK_HEADER([webp/decode.h], [have_dep="yes"])
+
+if test "x${have_dep}"  = "xyes" ; then
+   AC_CHECK_LIB([webp],
+      [WebPDecodeRGBA],
+      [
+       evas_image_loader_[]$1[]_libs="-lwebp"
+      ],
+      [have_dep="no"]
+   )
+fi
+
+AC_SUBST([evas_image_loader_$1_cflags])
+AC_SUBST([evas_image_loader_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$3], [:])
+else
+  m4_default([$4], [:])
+fi
+
+])
+
 dnl use: EVAS_CHECK_LOADER_DEP_GENERIC(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN([EVAS_CHECK_LOADER_DEP_GENERIC],
index a11c635..9a1e01b 100644 (file)
@@ -50,6 +50,7 @@ static const struct ext_loader_s map_loaders[] =
    MATCHING(".bmp", "bmp"),
    MATCHING(".tga", "tga"),
    MATCHING(".wbmp", "wbmp"),
+   MATCHING(".webp", "webp"),
    MATCHING(".ico", "ico"),
    MATCHING(".cur", "ico"),
    MATCHING(".psd", "psd")
@@ -57,7 +58,7 @@ static const struct ext_loader_s map_loaders[] =
 
 static const char *loaders_name[] =
 { /* in order of most likely needed */
-  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb"
+  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb"
 };
 
 Eina_Bool
index 46222c8..96d0c5e 100644 (file)
@@ -42,6 +42,10 @@ if BUILD_LOADER_WBMP
 SUBDIRS += wbmp
 endif
 
+if BUILD_LOADER_WEBP
+SUBDIRS += webp
+endif
+
 if BUILD_LOADER_XPM
 SUBDIRS += xpm
 endif
diff --git a/legacy/evas/src/bin/loaders/webp/Makefile.am b/legacy/evas/src/bin/loaders/webp/Makefile.am
new file mode 100644 (file)
index 0000000..9f186ff
--- /dev/null
@@ -0,0 +1,33 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_webp_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_WEBP
+#if !EVAS_STATIC_BUILD_WEBP
+
+pkgdir = $(libdir)/evas/cserve2/loaders/webp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_webp.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_webp_libs@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_webp.la
+#libevas_loader_webp_la_SOURCES = evas_image_load_webp.c
+#libevas_loader_webp_la_LIBADD = @evas_image_loader_webp_libs@
+
+#endif
+endif
diff --git a/legacy/evas/src/bin/loaders/webp/evas_image_load_webp.c b/legacy/evas/src/bin/loaders/webp/evas_image_load_webp.c
new file mode 100644 (file)
index 0000000..6adf0ea
--- /dev/null
@@ -0,0 +1,135 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <webp/decode.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+
+static Eina_Bool
+evas_image_load_file_head_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+   WebPDecoderConfig config;
+   FILE *f;
+   size_t header_size = 30;
+   uint8_t header[30];
+   
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+   if (fread(header, header_size, 1, f) != 1)
+   {
+      fclose(f);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      return EINA_FALSE;
+   }
+   fclose(f);
+   
+   if (!WebPInitDecoderConfig(&config))
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   if (WebPGetFeatures(header, header_size, &config.input) != VP8_STATUS_OK)
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   
+   ilp->w = config.input.width;
+   ilp->h = config.input.height;
+   ilp->alpha = config.input.has_alpha;
+   
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+   FILE *f;
+   size_t file_size;
+   uint8_t *data, *decoded;
+   int width, height;
+   
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (fseek(f, 0, SEEK_END) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   file_size = ftell(f);
+   if (fseek(f, 0, SEEK_SET) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+
+   data = malloc(file_size);
+   if (!data)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto close_file;
+   }
+   if (fread(data, file_size, 1, f) != 1)
+   {
+      free(data);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   fclose(f);
+
+   decoded = WebPDecodeBGRA(data, file_size, &width, &height);
+   memcpy(ilp->buffer, decoded, width * height * 4);
+   evas_cserve2_image_premul(ilp);
+   
+   free(decoded);
+   free(data);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+
+close_file:
+   fclose(f);
+   return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+   EVAS_CSERVE2_MODULE_API_VERSION,
+   "webp",
+   evas_image_load_file_head_webp,
+   evas_image_load_file_data_webp
+};
+
+static Eina_Bool
+module_init(void)
+{
+   return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
index 386bb76..d88cbec 100644 (file)
@@ -47,6 +47,7 @@ static const struct ext_loader_s loaders[] =
    MATCHING(".bmp", "bmp"),
    MATCHING(".tga", "tga"),
    MATCHING(".wbmp", "wbmp"),
+   MATCHING(".webp", "webp"),
    MATCHING(".ico", "ico"),
    MATCHING(".cur", "ico"),
    MATCHING(".psd", "psd"),
@@ -127,7 +128,7 @@ static const struct ext_loader_s loaders[] =
 
 static const char *loaders_name[] =
 { /* in order of most likely needed */
-  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb", "generic"
+  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb", "generic"
 };
 
 struct evas_image_foreach_loader_data
index 3c9378d..7bc52bc 100644 (file)
@@ -123,6 +123,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, svg);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tga);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, webp);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, edb);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, eet);
@@ -233,6 +234,9 @@ static const struct {
 #ifdef EVAS_STATIC_BUILD_WBMP
   EVAS_EINA_STATIC_MODULE_USE(image_loader, wbmp),
 #endif
+#ifdef EVAS_STATIC_BUILD_WEBP
+  EVAS_EINA_STATIC_MODULE_USE(image_loader, webp),
+#endif
 #ifdef EVAS_STATIC_BUILD_XPM
   EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
 #endif
index b7ed9a5..8122e56 100644 (file)
@@ -86,6 +86,12 @@ SUBDIRS += wbmp
 endif
 endif
 
+if BUILD_LOADER_WEBP
+if !EVAS_STATIC_BUILD_WEBP
+SUBDIRS += webp
+endif
+endif
+
 if BUILD_LOADER_XPM
 if !EVAS_STATIC_BUILD_XPM
 SUBDIRS += xpm
diff --git a/legacy/evas/src/modules/loaders/webp/Makefile.am b/legacy/evas/src/modules/loaders/webp/Makefile.am
new file mode 100644 (file)
index 0000000..c10b5b9
--- /dev/null
@@ -0,0 +1,35 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@evas_image_loader_webp_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_WEBP
+if !EVAS_STATIC_BUILD_WEBP
+
+pkgdir = $(libdir)/evas/modules/loaders/webp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_webp.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_webp_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_loader_webp.la
+
+libevas_loader_webp_la_SOURCES = evas_image_load_webp.c
+libevas_loader_webp_la_LIBADD = @evas_image_loader_webp_libs@
+
+endif
+endif
diff --git a/legacy/evas/src/modules/loaders/webp/evas_image_load_webp.c b/legacy/evas/src/modules/loaders/webp/evas_image_load_webp.c
new file mode 100644 (file)
index 0000000..5b23910
--- /dev/null
@@ -0,0 +1,165 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <webp/decode.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+static Eina_Bool evas_image_load_file_head_webp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+static Evas_Image_Load_Func evas_image_load_webp_func =
+{
+  EINA_TRUE,
+  evas_image_load_file_head_webp,
+  evas_image_load_file_data_webp,
+  NULL,
+  EINA_FALSE
+};
+
+
+static Eina_Bool
+evas_image_load_file_head_webp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   WebPDecoderConfig config;
+   FILE *f;
+   size_t header_size = 30;
+   uint8_t header[30];
+
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+   if (fread(header, header_size, 1, f) != 1)
+   {
+      fclose(f);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      return EINA_FALSE;
+   }
+   fclose(f);
+
+   if (!WebPInitDecoderConfig(&config))
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   if (WebPGetFeatures(header, header_size, &config.input) != VP8_STATUS_OK)
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+
+   ie->w = config.input.width;
+   ie->h = config.input.height;
+   ie->flags.alpha = config.input.has_alpha;
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   FILE *f;
+   size_t file_size;
+   uint8_t *data, *decoded, *surface;
+   int width, height;
+
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (fseek(f, 0, SEEK_END) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   file_size = ftell(f);
+
+   if (fseek(f, 0, SEEK_SET) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+
+   data = malloc(file_size);
+   if (!data)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto close_file;
+   }
+   if (fread(data, file_size, 1, f) != 1)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto free_data;
+   }
+
+   evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+   surface = evas_cache_image_pixels(ie);
+   if (!surface)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto free_data;
+   }
+
+   decoded = WebPDecodeBGRA(data, file_size, &width, &height);
+   memcpy(surface, decoded, width * height * 4);
+   evas_common_image_premul(ie);  
+
+   free(decoded);
+   free(data);
+   fclose(f);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+
+free_data:
+   free(data);
+
+close_file:
+   fclose(f);
+   return EINA_FALSE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_webp_func);
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em __UNUSED__)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+   EVAS_MODULE_API_VERSION,
+   "webp",
+   "none",
+   {
+     module_open,
+     module_close
+   }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, webp);
+
+#ifndef EVAS_STATIC_BUILD_WEBP
+EVAS_EINA_MODULE_DEFINE(image_loader, webp);
+#endif