diff --git a/ChangeLog b/ChangeLog index ca6a15ef38..966f18a1ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-03-08 Igor Murzov + + * Add WebP image saver. + 2013-03-07 Jiyoun Park (Jypark) * Ecore_x: Add manual render code before deiconify @@ -603,4 +607,7 @@ * Fix EINA_INLIST_FOREACH_SAFE macro to work when inlist is not the first item in the struct. +2012-09-03 Igor Murzov + + * Add WebP image loader. diff --git a/NEWS b/NEWS index 002ccdff27..c4dbeb3c85 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,7 @@ Additions: - Add window profile support. * ecore_getopt: add ECORE_GETOPT_ACTION_BREAK * evas: + - Add WebP image loader and saver modules. - Add ellipsis support in Evas_Object_Text. - Add EVAS_GL_LINE_OFFSET_HACK_DISABLE to turn off line shift correction by evas. - Add EVAS_GL_DIRECT_MEM_OPT to enable on-demand fallback memory allocation policy for EvasGL direct rendering. diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index e6ecfd4f0b..1bd921ddc1 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -1264,7 +1264,7 @@ endif if BUILD_LOADER_WEBP if EVAS_STATIC_BUILD_WEBP -lib_evas_libevas_la_SOURCES += modules/evas/loaders/webp/evas_image_load_webp.c +lib_evas_libevas_la_SOURCES += modules/evas/loaders/webp/evas_image_load_webp.c modules/evas/savers/webp/evas_image_save_webp.c lib_evas_libevas_la_CPPFLAGS += @evas_image_loader_webp_cflags@ lib_evas_libevas_la_LIBADD += @evas_image_loader_webp_libs@ else @@ -1281,6 +1281,20 @@ modules_evas_loaders_webp_module_la_LIBADD = \ modules_evas_loaders_webp_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ modules_evas_loaders_webp_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ modules_evas_loaders_webp_module_la_LIBTOOLFLAGS = --tag=disable-static + +saverwebppkgdir = $(libdir)/evas/modules/savers/webp/$(MODULE_ARCH) +saverwebppkg_LTLIBRARIES = modules/evas/savers/webp/module.la +modules_evas_savers_webp_module_la_SOURCES = modules/evas/savers/webp/evas_image_save_webp.c +modules_evas_savers_webp_module_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/evas/include \ +@EVAS_CFLAGS@ \ +@evas_image_loader_webp_cflags@ +modules_evas_savers_webp_module_la_LIBADD = \ +@USE_EVAS_LIBS@ \ +@evas_image_loader_webp_libs@ +modules_evas_savers_webp_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ +modules_evas_savers_webp_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ +modules_evas_savers_webp_module_la_LIBTOOLFLAGS = --tag=disable-static endif endif diff --git a/src/lib/evas/common/evas_image_save.c b/src/lib/evas/common/evas_image_save.c index d97cc5bb20..ad69a10e53 100644 --- a/src/lib/evas/common/evas_image_save.c +++ b/src/lib/evas/common/evas_image_save.c @@ -28,6 +28,8 @@ evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key if ((!strcasecmp(p, "eet")) || (!strcasecmp(p, "edj")) || (!strcasecmp(p, "eap"))) saver = "eet"; + if (!strcasecmp(p, "webp")) + saver = "webp"; } if (saver) diff --git a/src/lib/evas/file/evas_module.c b/src/lib/evas/file/evas_module.c index 0a5e302a22..03ab41cf61 100644 --- a/src/lib/evas/file/evas_module.c +++ b/src/lib/evas/file/evas_module.c @@ -133,6 +133,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, eet); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, jpeg); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png); EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff); +EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, webp); static const struct { Eina_Bool (*init)(void); @@ -221,6 +222,9 @@ static const struct { #endif #ifdef EVAS_STATIC_BUILD_TIFF EVAS_EINA_STATIC_MODULE_USE(image_saver, tiff), +#endif +#ifdef EVAS_STATIC_BUILD_WEBP + EVAS_EINA_STATIC_MODULE_USE(image_saver, webp), #endif { NULL, NULL } }; diff --git a/src/modules/evas/savers/webp/evas_image_save_webp.c b/src/modules/evas/savers/webp/evas_image_save_webp.c new file mode 100644 index 0000000000..9c2cbd1542 --- /dev/null +++ b/src/modules/evas/savers/webp/evas_image_save_webp.c @@ -0,0 +1,108 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "evas_common.h" +#include "evas_private.h" + +static int evas_image_save_file_webp(RGBA_Image *im, const char *file, const char *key, int quality, int compress); + +static Evas_Image_Save_Func evas_image_save_webp_func = +{ + evas_image_save_file_webp +}; + +static int writer(const uint8_t *data, size_t data_size, const WebPPicture *const pic) +{ + FILE *out = (FILE *)pic->custom_ptr; + return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1; +} + +static int +save_image_webp(RGBA_Image *im, const char *file, int quality) +{ + WebPPicture picture; + WebPConfig config; + int result = 0; + + if (!im || !im->image.data || !file) + return 0; + + if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) + return 0; + + picture.width = im->cache_entry.w; + picture.height = im->cache_entry.h; + picture.use_argb = 1; + if (im->cache_entry.flags.alpha) + picture.colorspace |= WEBP_CSP_ALPHA_BIT; + else + picture.colorspace &= ~WEBP_CSP_ALPHA_BIT; + + if (!WebPPictureAlloc(&picture)) // allocates picture.argb + return 0; + memcpy(picture.argb, im->image.data, picture.width * picture.height * sizeof(DATA32)); + evas_common_convert_argb_unpremul(picture.argb, picture.width * picture.height); + + if (quality == 100) + config.lossless = 1; + else + config.quality = quality; + // config.method = 6; // slower, but better quality + + if (!WebPValidateConfig(&config)) + goto free_picture; + + FILE *f = fopen(file, "wb"); + if (f == NULL) + goto free_picture; + + picture.writer = writer; + picture.custom_ptr = (void *)f; + + result = WebPEncode(&config, &picture); + + fclose(f); + free_picture: + WebPPictureFree(&picture); + + return result; +} + +static int evas_image_save_file_webp(RGBA_Image *im, const char *file, const char *key EINA_UNUSED, int quality, int compress EINA_UNUSED) +{ + return save_image_webp(im, file, quality); +} + +static int +module_open(Evas_Module *em) +{ + if (!em) return 0; + em->functions = (void *)(&evas_image_save_webp_func); + return 1; +} + +static void +module_close(Evas_Module *em EINA_UNUSED) +{ +} + +static Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + "webp", + "none", + { + module_open, + module_close + } +}; + +EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, webp); + +#ifndef EVAS_STATIC_BUILD_WEBP +EVAS_EINA_MODULE_DEFINE(image_saver, webp); +#endif