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: 75951devs/devilhorns/wayland_egl
parent
e7d316dbc2
commit
e42648154f
15 changed files with 436 additions and 2 deletions
@ -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 |
@ -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); |
@ -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 |
@ -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 |
Loading…
Reference in new issue