Hi,

this patch is adding support for google webp image format, if you
don't know it a quick recap is to say that according to their tests
it's better than png and jpeg.

Follow the link below for some more details:
https://developers.google.com/speed/webp/

patch inlined and enclosed.

ps: next target is svg support

Enjoy!
david

---
 configure.ac          |   10 +++-
 m4/wm_imgfmt_check.m4 |   20 ++++++++
 wrlib/Makefile.am     |    4 ++
 wrlib/imgformat.h     |    3 +-
 wrlib/load.c          |   44 +++++++++++++++-
 wrlib/load_webp.c     |  137 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 215 insertions(+), 3 deletions(-)
 create mode 100644 wrlib/load_webp.c

diff --git a/configure.ac b/configure.ac
index d642489..6c06dcb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -678,6 +678,15 @@ AC_ARG_ENABLE([tiff],
     [enable_tiff=auto])
 WM_IMGFMT_CHECK_TIFF

+dnl WEBP Support
+dnl ===========
+AC_ARG_ENABLE([webp],
+    [AS_HELP_STRING([--disable-webp], [disable WEBP support through libwebp])],
+    [AS_CASE(["$enableval"],
+        [yes|no], [],
+        [AC_MSG_ERROR([bad value $enableval for --enable-webp])] )],
+    [enable_webp=auto])
+WM_IMGFMT_CHECK_WEBP

 dnl PPM Support
 dnl ===========
@@ -685,7 +694,6 @@ dnl ===========
 # We are not using any external library like libppm
 supported_gfx="$supported_gfx builtin-PPM"

-
 # Choice of the default format for icons
 AS_IF([test "x$enable_tiff" != "xno"],
     [ICONEXT="tiff"],
diff --git a/m4/wm_imgfmt_check.m4 b/m4/wm_imgfmt_check.m4
index 02245d2..0881cdd 100644
--- a/m4/wm_imgfmt_check.m4
+++ b/m4/wm_imgfmt_check.m4
@@ -221,3 +221,23 @@ AS_IF([test "x$enable_xpm" = "xno"],
     ])
 AM_CONDITIONAL([USE_XPM], [test "x$enable_xpm" != "xno"])dnl
 ]) dnl AC_DEFUN
+
+# WM_IMGFMT_CHECK_WEBP
+# -------------------
+#
+# Check for WEBP file support through 'libwebp'
+# The check depends on variable 'enable_webp' being either:
+#   yes  - detect, fail if not found
+#   no   - do not detect, disable support
+#   auto - detect, disable if not found
+#
+# When not found, append info to variable 'unsupported'
+AC_DEFUN_ONCE([WM_IMGFMT_CHECK_WEBP],
+[WM_LIB_CHECK([WEBP], ["-lwebp"], [VP8DecodeLayer], [$XLFLAGS $XLIBS],
+    [wm_save_CFLAGS="$CFLAGS"
+     AS_IF([wm_fn_lib_try_compile "webp/decode.h" "" "return 0" ""],
+         [],
+         [AC_MSG_ERROR([found $CACHEVAR but could not find
appropriate header - are you missing libwebp-dev package?])])
+     CFLAGS="$wm_save_CFLAGS"],
+    [supported_gfx], [GFXLIBS])dnl
+]) dnl AC_DEFUN
diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am
index db766ae..48af352 100644
--- a/wrlib/Makefile.am
+++ b/wrlib/Makefile.am
@@ -60,6 +60,10 @@ else
 libwraster_la_SOURCES += load_xpm_normalized.c
 endif

+if USE_WEBP
+libwraster_la_SOURCES += load_webp.c
+endif
+
 AM_CPPFLAGS = $(DFLAGS) @HEADER_SEARCH_PATH@

 libwraster_la_LIBADD = @LIBRARY_SEARCH_PATH@ @GFXLIBS@ @XLIBS@ @LIBXMU@ -lm
diff --git a/wrlib/imgformat.h b/wrlib/imgformat.h
index 07b021a..98e8c3d 100644
--- a/wrlib/imgformat.h
+++ b/wrlib/imgformat.h
@@ -38,7 +38,8 @@ typedef enum {
  IM_PNG     =  3,
  IM_PPM     =  4,
  IM_JPEG    =  5,
- IM_GIF     =  6
+ IM_GIF     =  6,
+ IM_WEBP    =  7
 } WRImgFormat;

 /* How many image types we have. */
diff --git a/wrlib/load.c b/wrlib/load.c
index 061a50d..e834c9e 100644
--- a/wrlib/load.c
+++ b/wrlib/load.c
@@ -3,6 +3,7 @@
  * Raster graphics library
  *
  * Copyright (c) 1997-2003 Alfredo K. Kojima
+ * Copyright (c) 2014 Window Maker Team
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -37,6 +38,10 @@
 #include <png.h>
 #endif

+#ifdef USE_WEBP
+#include <webp/decode.h>
+#endif
+
 #include "wraster.h"
 #include "imgformat.h"

@@ -92,6 +97,9 @@ char **RSupportedFileFormats(void)
 #ifdef USE_GIF
  tmp[i++] = "GIF";
 #endif
+#ifdef USE_WEBP
+ tmp[i++] = "WEBP";
+#endif
  tmp[i] = NULL;

  return tmp;
@@ -190,6 +198,12 @@ RImage *RLoadImage(RContext * context, const char
*file, int index)
  break;
 #endif /* USE_GIF */

+#ifdef USE_WEBP
+ case IM_WEBP:
+ image = RLoadWEBP(file, index);
+ break;
+#endif /* USE_WEBP */
+
  case IM_PPM:
  image = RLoadPPM(file);
  break;
@@ -264,6 +278,11 @@ char *RGetImageFileFormat(const char *file)
  return "GIF";
 #endif /* USE_GIF */

+#ifdef USE_WEBP
+ case IM_WEBP:
+ return "WEBP";
+#endif /* USE_WEBP */
+
  case IM_PPM:
  return "PPM";

@@ -275,7 +294,7 @@ char *RGetImageFileFormat(const char *file)
 static WRImgFormat identFile(const char *path)
 {
  FILE *file;
- unsigned char buffer[7];
+ unsigned char buffer[17];
  size_t nread;

  assert(path != NULL);
@@ -319,5 +338,28 @@ static WRImgFormat identFile(const char *path)
  if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F' &&
buffer[3] == '8')
  return IM_GIF;

+#ifdef USE_WEBP
+ /* check for WEBP */
+ if (buffer[ 0] == 'R' &&
+                     buffer[ 1] == 'I' &&
+                     buffer[ 2] == 'F' &&
+                     buffer[ 3] == 'F' &&
+                     buffer[ 8] == 'W' &&
+     buffer[ 9] == 'E' &&
+                     buffer[10] == 'B' &&
+                     buffer[11] == 'P' &&
+                     buffer[12] == 'V' &&
+                     buffer[13] == 'P' &&
+                     buffer[14] == '8' &&
+#if WEBP_DECODER_ABI_VERSION < 0x0003 /* old versions don't support
WEBPVP8X and WEBPVP8L */
+ buffer[15] == ' ')
+#else
+ (buffer[15] == ' ' || buffer[15] == 'X' || buffer[15] == 'L'))
+#endif
+#endif
+
+ return IM_WEBP;
+
+
  return IM_UNKNOWN;
 }
diff --git a/wrlib/load_webp.c b/wrlib/load_webp.c
new file mode 100644
index 0000000..d69a107
--- /dev/null
+++ b/wrlib/load_webp.c
@@ -0,0 +1,137 @@
+/* load_webp.c - load WEBP image from file
+ *
+ * Raster graphics library
+ *
+ * Copyright (c) 2014 Window Maker Team
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include <X11/Xlib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <webp/decode.h>
+
+#include "wraster.h"
+#include "imgformat.h"
+
+RImage *
+RLoadWEBP(const char *file_name)
+{
+ FILE *file;
+ RImage *image = NULL;
+ char buffer[20];
+ int raw_data_size;
+ int start;
+ int r;
+ uint8_t *raw_data;
+ WebPBitstreamFeatures features;
+ uint8_t *ret = NULL;
+
+ file = fopen(file_name, "rb");
+ if (!file) {
+ RErrorCode = RERR_OPEN;
+ return NULL;
+ }
+ start = ftell(file);
+
+ if (!fread(buffer, sizeof(buffer), 1, file)) {
+ RErrorCode = RERR_BADIMAGEFILE;
+ fclose(file);
+ return NULL;
+ }
+
+
+ if (!(buffer[0] == 'R' &&
+      buffer[1] == 'I' &&
+      buffer[2] == 'F' &&
+      buffer[3] == 'F' &&
+      buffer[8] == 'W' &&
+      buffer[9] == 'E' &&
+      buffer[10] == 'B' &&
+      buffer[11] == 'P' &&
+      buffer[12] == 'V' && buffer[13] == 'P' && buffer[14] == '8' &&
+#if WEBP_DECODER_ABI_VERSION < 0x0003 /* old versions don't support
WEBPVP8X and WEBPVP8L */
+      buffer[15] == ' ')) {
+#else
+      (buffer[15] == ' ' || buffer[15] == 'X' || buffer[15] == 'L'))) {
+#endif
+ RErrorCode = RERR_BADFORMAT;
+ fclose(file);
+ return NULL;
+ }
+
+
+ fseek(file, 0, SEEK_END);
+ raw_data_size = ftell(file);
+
+ if (raw_data_size <= 0) {
+ fprintf(stderr, "Failed to find the WEBP image size\n");
+ return NULL;
+ }
+
+ fseek(file, start, SEEK_SET);
+
+ raw_data = (uint8_t *) malloc(raw_data_size);
+
+ if (!raw_data) {
+ fprintf(stderr, "Failed to allocate enought buffer for WEBP\n");
+ return NULL;
+ }
+
+ r = fread(raw_data, 1, raw_data_size, file);
+
+ if (r != raw_data_size) {
+ fprintf(stderr, "Failed to read WEBP\n");
+ return NULL;
+ }
+
+ if (WebPGetFeatures(raw_data, raw_data_size, &features) !=
+    VP8_STATUS_OK) {
+ fprintf(stderr, "WebPGetFeatures has failed\n");
+ return NULL;
+ }
+
+ if (features.has_alpha) {
+ image = RCreateImage(features.width, features.height, True);
+ if (!image)
+ return NULL;
+ ret =
+    WebPDecodeRGBAInto(raw_data, raw_data_size, image->data,
+       features.width * features.height * 4,
+       features.width * 4);
+ } else {
+ image = RCreateImage(features.width, features.height, False);
+ if (!image)
+ return NULL;
+ ret =
+    WebPDecodeRGBInto(raw_data, raw_data_size, image->data,
+      features.width * features.height * 3,
+      features.width * 3);
+ }
+
+ if (!ret) {
+ fprintf(stderr, "Failed to decode WEBP\n");
+ return NULL;
+ }
+
+ fclose(file);
+ return image;
+}
-- 
1.7.10.4

Attachment: 0001-Added-support-for-webp-image.patch
Description: Binary data

Reply via email to