From: Kristian Høgsberg Date: Wed, 8 Feb 2012 17:46:57 +0000 (-0500) Subject: Add support for webp image format X-Git-Tag: upstream/0.1.8~2928 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d5437c48d17cb4bf5c861d62ce59e4f9d490050;p=profile%2Fivi%2Fweston-ivi-shell.git Add support for webp image format --- diff --git a/clients/cairo-util.c b/clients/cairo-util.c index 2f780a7..df2fb1b 100644 --- a/clients/cairo-util.c +++ b/clients/cairo-util.c @@ -21,6 +21,8 @@ * OF THIS SOFTWARE. */ +#include "../config.h" + #include #include #include @@ -32,6 +34,10 @@ #include #include +#ifdef HAVE_WEBP +#include +#endif + #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) void @@ -514,14 +520,98 @@ load_png(FILE *fp) width, height, stride); } +#ifdef HAVE_WEBP + +static cairo_surface_t * +load_webp(FILE *fp) +{ + WebPDecoderConfig config; + uint8_t buffer[16 * 1024]; + int len; + VP8StatusCode status; + WebPIDecoder *idec; + + if (!WebPInitDecoderConfig(&config)) { + fprintf(stderr, "Library version mismatch!\n"); + return NULL; + } + + /* webp decoding api doesn't seem to specify a min size that's + usable for GetFeatures, but 256 works... */ + len = fread(buffer, 1, 256, fp); + status = WebPGetFeatures(buffer, len, &config.input); + if (status != VP8_STATUS_OK) { + fprintf(stderr, "failed to parse webp header\n"); + WebPFreeDecBuffer(&config.output); + return NULL; + } + + config.output.colorspace = MODE_BGRA; + config.output.u.RGBA.stride = + cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, + config.input.width); + config.output.u.RGBA.size = + config.output.u.RGBA.stride * config.input.height; + config.output.u.RGBA.rgba = + malloc(config.output.u.RGBA.stride * config.input.height); + config.output.is_external_memory = 1; + if (!config.output.u.RGBA.rgba) { + WebPFreeDecBuffer(&config.output); + return NULL; + } + + rewind(fp); + idec = WebPINewDecoder(&config.output); + if (!idec) { + WebPFreeDecBuffer(&config.output); + return NULL; + } + + while (!feof(fp)) { + len = fread(buffer, 1, sizeof buffer, fp); + status = WebPIAppend(idec, buffer, len); + if (status != VP8_STATUS_OK) { + fprintf(stderr, "webp decode status %d\n", status); + WebPIDelete(idec); + WebPFreeDecBuffer(&config.output); + return NULL; + } + } + + WebPIDelete(idec); + WebPFreeDecBuffer(&config.output); + + return cairo_image_surface_create_for_data (config.output.u.RGBA.rgba, + CAIRO_FORMAT_RGB24, + config.input.width, + config.input.height, + config.output.u.RGBA.stride); +} + +#endif + + +struct image_loader { + char header[4]; + int header_size; + cairo_surface_t *(*load)(FILE *fp); +}; + +static const struct image_loader loaders[] = { + { { 0x89, 'P', 'N', 'G' }, 4, load_png }, + { { 0xff, 0xd8 }, 2, load_jpeg }, +#ifdef HAVE_WEBP + { { 'R', 'I', 'F', 'F' }, 4, load_webp } +#endif +}; + cairo_surface_t * load_image(const char *filename) { cairo_surface_t *surface; - static const unsigned char png_header[] = { 0x89, 'P', 'N', 'G' }; - static const unsigned char jpeg_header[] = { 0xff, 0xd8 }; unsigned char header[4]; FILE *fp; + int i; fp = fopen(filename, "rb"); if (fp == NULL) @@ -529,18 +619,22 @@ load_image(const char *filename) fread(header, sizeof header, 1, fp); rewind(fp); - if (memcmp(header, png_header, sizeof png_header) == 0) - surface = load_png(fp); - else if (memcmp(header, jpeg_header, sizeof jpeg_header) == 0) - surface = load_jpeg(fp); - else { + for (i = 0; i < ARRAY_LENGTH(loaders); i++) { + if (memcmp(header, loaders[i].header, + loaders[i].header_size) == 0) { + surface = loaders[i].load(fp); + break; + } + } + + fclose(fp); + + if (i == ARRAY_LENGTH(loaders)) { fprintf(stderr, "unrecognized file header for %s: " "0x%02x 0x%02x 0x%02x 0x%02x\n", filename, header[0], header[1], header[2], header[3]); surface = NULL; } - fclose(fp); - return surface; } diff --git a/configure.ac b/configure.ac index a2bb537..02f4040 100644 --- a/configure.ac +++ b/configure.ac @@ -123,11 +123,16 @@ if test x$enable_clients == xyes; then [have_poppler=yes], [have_poppler=no]) PKG_CHECK_MODULES(CAIRO_EGL, [cairo-egl >= 1.11.3 $cairo_modules], [have_cairo_egl=yes], [have_cairo_egl=no]) - AS_IF([test "x$have_cairo_egl" = "xyes"], [AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])], [AC_MSG_WARN([Cairo-EGL not found - clients will use cairo image])]) + PKG_CHECK_MODULES(WEBP, [libwebp], [have_webp=yes], [have_webp=no]) + AS_IF([test "x$have_webp" = "xyes"], + [AC_DEFINE([HAVE_WEBP], [1], [Have webp])]) + CLIENT_LIBS="$CLIENT_LIBS $WEBP_LIBS" + CLIENT_CFLAGS="$CLIENT_CFLAGS $WEBP_CFLAGS" + AC_CHECK_LIB([jpeg], [jpeg_CreateDecompress], have_jpeglib=yes) if test x$have_jpeglib == xyes; then CLIENT_LIBS="$CLIENT_LIBS -ljpeg"