Evas: heif module is dlopen'ed
The reason is that for newer versions, libheif should be initialized with heif_init(). This way, we call this function if the symbol exists.
This commit is contained in:
parent
5f9ba628ad
commit
4ee1a77118
|
@ -21,7 +21,7 @@ evas_image_loaders_file = [
|
||||||
['eet', 'static', [eet]],
|
['eet', 'static', [eet]],
|
||||||
['generic', 'shared', [rt]],
|
['generic', 'shared', [rt]],
|
||||||
['gif', 'shared', [giflib]],
|
['gif', 'shared', [giflib]],
|
||||||
['heif', 'shared', [heif]],
|
['heif', 'shared', []],
|
||||||
['ico', 'shared', []],
|
['ico', 'shared', []],
|
||||||
['jpeg', 'static', [jpeg]],
|
['jpeg', 'static', [jpeg]],
|
||||||
['jp2k', 'shared', [libopenjp2]],
|
['jp2k', 'shared', [libopenjp2]],
|
||||||
|
|
|
@ -16,6 +16,86 @@ struct _Evas_Loader_Internal
|
||||||
};
|
};
|
||||||
|
|
||||||
static int _evas_loader_heif_log_dom = -1;
|
static int _evas_loader_heif_log_dom = -1;
|
||||||
|
static Eina_Module *_evas_loader_heif_mod = NULL;
|
||||||
|
|
||||||
|
#define LOAD(x) \
|
||||||
|
if (!_evas_loader_heif_mod) { \
|
||||||
|
if ((_evas_loader_heif_mod = eina_module_new(x))) { \
|
||||||
|
if (!eina_module_load(_evas_loader_heif_mod)) { \
|
||||||
|
eina_module_free(_evas_loader_heif_mod); \
|
||||||
|
_evas_loader_heif_mod = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SYM(x) \
|
||||||
|
if (!(x ## _f = eina_module_symbol_get(_evas_loader_heif_mod, #x))) { \
|
||||||
|
ERR("Cannot find symbol '%s' in '%s'", \
|
||||||
|
#x, eina_module_file_get(_evas_loader_heif_mod)); \
|
||||||
|
goto error; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// heif_check_filetype
|
||||||
|
typedef enum heif_filetype_result (*heif_check_filetype_t)(const uint8_t* data,
|
||||||
|
int len);
|
||||||
|
static heif_check_filetype_t heif_check_filetype_f = NULL;
|
||||||
|
|
||||||
|
// heif_context_alloc
|
||||||
|
typedef struct heif_context* (*heif_context_alloc_t)(void);
|
||||||
|
static heif_context_alloc_t heif_context_alloc_f = NULL;
|
||||||
|
|
||||||
|
// heif_context_free
|
||||||
|
typedef void (*heif_context_free_t)(struct heif_context*);
|
||||||
|
static heif_context_free_t heif_context_free_f = NULL;
|
||||||
|
|
||||||
|
// heif_context_get_primary_image_handle
|
||||||
|
typedef struct heif_error (*heif_context_get_primary_image_handle_t)(struct heif_context* ctx,
|
||||||
|
struct heif_image_handle**);
|
||||||
|
static heif_context_get_primary_image_handle_t heif_context_get_primary_image_handle_f = NULL;
|
||||||
|
|
||||||
|
// heif_context_read_from_memory_without_copy
|
||||||
|
typedef struct heif_error (*heif_context_read_from_memory_without_copy_t)(struct heif_context*,
|
||||||
|
const void* mem, size_t size,
|
||||||
|
const struct heif_reading_options*);
|
||||||
|
static heif_context_read_from_memory_without_copy_t heif_context_read_from_memory_without_copy_f = NULL;
|
||||||
|
|
||||||
|
// heif_decode_image
|
||||||
|
typedef struct heif_error (*heif_decode_image_t)(const struct heif_image_handle* in_handle,
|
||||||
|
struct heif_image** out_img,
|
||||||
|
enum heif_colorspace colorspace,
|
||||||
|
enum heif_chroma chroma,
|
||||||
|
const struct heif_decoding_options* options);
|
||||||
|
static heif_decode_image_t heif_decode_image_f = NULL;
|
||||||
|
|
||||||
|
// heif_deinit
|
||||||
|
typedef void (*heif_deinit_t)();
|
||||||
|
static heif_deinit_t heif_deinit_f = NULL;
|
||||||
|
|
||||||
|
// heif_image_get_plane_readonly
|
||||||
|
typedef const uint8_t* (*heif_image_get_plane_readonly_t)(const struct heif_image*,
|
||||||
|
enum heif_channel channel,
|
||||||
|
int* out_stride);
|
||||||
|
static heif_image_get_plane_readonly_t heif_image_get_plane_readonly_f = NULL;
|
||||||
|
|
||||||
|
// heif_image_handle_get_height
|
||||||
|
typedef int (*heif_image_handle_get_height_t)(const struct heif_image_handle* handle);
|
||||||
|
static heif_image_handle_get_height_t heif_image_handle_get_height_f = NULL;
|
||||||
|
|
||||||
|
// heif_image_handle_get_width
|
||||||
|
typedef int (*heif_image_handle_get_width_t)(const struct heif_image_handle* handle);
|
||||||
|
static heif_image_handle_get_width_t heif_image_handle_get_width_f = NULL;
|
||||||
|
|
||||||
|
// heif_image_handle_has_alpha_channel
|
||||||
|
typedef int (*heif_image_handle_has_alpha_channel_t)(const struct heif_image_handle*);
|
||||||
|
static heif_image_handle_has_alpha_channel_t heif_image_handle_has_alpha_channel_f = NULL;
|
||||||
|
|
||||||
|
// heif_init
|
||||||
|
typedef struct heif_error (*heif_init_t)(struct heif_init_params*);
|
||||||
|
static heif_init_t heif_init_f = NULL;
|
||||||
|
|
||||||
|
// heif_image_handle_release
|
||||||
|
typedef void (*heif_image_handle_release_t)(const struct heif_image_handle*);
|
||||||
|
static heif_image_handle_release_t heif_image_handle_release_f = NULL;
|
||||||
|
|
||||||
#ifdef ERR
|
#ifdef ERR
|
||||||
# undef ERR
|
# undef ERR
|
||||||
|
@ -45,14 +125,14 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
|
||||||
|
|
||||||
/* heif file must have a 12 bytes long header */
|
/* heif file must have a 12 bytes long header */
|
||||||
if ((length < 12) ||
|
if ((length < 12) ||
|
||||||
(heif_check_filetype(map, length) == heif_filetype_no))
|
(heif_check_filetype_f(map, length) == heif_filetype_no))
|
||||||
{
|
{
|
||||||
INF("HEIF header invalid");
|
INF("HEIF header invalid");
|
||||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = heif_context_alloc();
|
ctx = heif_context_alloc_f();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
{
|
{
|
||||||
INF("cannot allocate heif_context");
|
INF("cannot allocate heif_context");
|
||||||
|
@ -60,7 +140,7 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = heif_context_read_from_memory_without_copy(ctx, map, length, NULL);
|
err = heif_context_read_from_memory_without_copy_f(ctx, map, length, NULL);
|
||||||
if (err.code != heif_error_Ok)
|
if (err.code != heif_error_Ok)
|
||||||
{
|
{
|
||||||
INF("%s", err.message);
|
INF("%s", err.message);
|
||||||
|
@ -68,7 +148,7 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
|
||||||
goto free_ctx;
|
goto free_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = heif_context_get_primary_image_handle(ctx, &handle);
|
err = heif_context_get_primary_image_handle_f(ctx, &handle);
|
||||||
if (err.code != heif_error_Ok)
|
if (err.code != heif_error_Ok)
|
||||||
{
|
{
|
||||||
INF("%s", err.message);
|
INF("%s", err.message);
|
||||||
|
@ -76,8 +156,8 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
|
||||||
goto free_ctx;
|
goto free_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop->w = heif_image_handle_get_width(handle);
|
prop->w = heif_image_handle_get_width_f(handle);
|
||||||
prop->h = heif_image_handle_get_height(handle);
|
prop->h = heif_image_handle_get_height_f(handle);
|
||||||
|
|
||||||
/* if size is invalid, we exit */
|
/* if size is invalid, we exit */
|
||||||
if ((prop->w < 1) || (prop->h < 1) ||
|
if ((prop->w < 1) || (prop->h < 1) ||
|
||||||
|
@ -91,15 +171,15 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
|
||||||
goto release_handle;
|
goto release_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop->alpha = !!heif_image_handle_has_alpha_channel(handle);
|
prop->alpha = !!heif_image_handle_has_alpha_channel_f(handle);
|
||||||
|
|
||||||
*error = EVAS_LOAD_ERROR_NONE;
|
*error = EVAS_LOAD_ERROR_NONE;
|
||||||
ret = EINA_TRUE;
|
ret = EINA_TRUE;
|
||||||
|
|
||||||
release_handle:
|
release_handle:
|
||||||
heif_image_handle_release(handle);
|
heif_image_handle_release_f(handle);
|
||||||
free_ctx:
|
free_ctx:
|
||||||
heif_context_free(ctx);
|
heif_context_free_f(ctx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +208,7 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
|
||||||
ctx = loader->ctx;
|
ctx = loader->ctx;
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
{
|
{
|
||||||
ctx = heif_context_alloc();
|
ctx = heif_context_alloc_f();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
{
|
{
|
||||||
INF("cannot allocate heif_context");
|
INF("cannot allocate heif_context");
|
||||||
|
@ -136,30 +216,30 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = heif_context_read_from_memory_without_copy(ctx,
|
err = heif_context_read_from_memory_without_copy_f(ctx,
|
||||||
map, length, NULL);
|
map, length, NULL);
|
||||||
if (err.code != heif_error_Ok)
|
if (err.code != heif_error_Ok)
|
||||||
{
|
{
|
||||||
INF("%s", err.message);
|
INF("%s", err.message);
|
||||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
heif_context_free(ctx);
|
heif_context_free_f(ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = heif_context_get_primary_image_handle(ctx, &handle);
|
err = heif_context_get_primary_image_handle_f(ctx, &handle);
|
||||||
if (err.code != heif_error_Ok)
|
if (err.code != heif_error_Ok)
|
||||||
{
|
{
|
||||||
INF("%s", err.message);
|
INF("%s", err.message);
|
||||||
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
heif_image_handle_release(handle);
|
heif_image_handle_release_f(handle);
|
||||||
heif_context_free(ctx);
|
heif_context_free_f(ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
loader->ctx = ctx;
|
loader->ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = heif_decode_image(handle, &img, heif_colorspace_RGB,
|
err = heif_decode_image_f(handle, &img, heif_colorspace_RGB,
|
||||||
prop->alpha ? heif_chroma_interleaved_RGBA
|
prop->alpha ? heif_chroma_interleaved_RGBA
|
||||||
: heif_chroma_interleaved_RGB,
|
: heif_chroma_interleaved_RGB,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -171,7 +251,7 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride);
|
data = heif_image_get_plane_readonly_f(img, heif_channel_interleaved, &stride);
|
||||||
|
|
||||||
dd = (unsigned char *)pixels;
|
dd = (unsigned char *)pixels;
|
||||||
ds = (unsigned char *)data;
|
ds = (unsigned char *)data;
|
||||||
|
@ -248,7 +328,7 @@ evas_image_load_file_close_heif(void *loader_data)
|
||||||
* loader is not filled and loader->ctx is NULL
|
* loader is not filled and loader->ctx is NULL
|
||||||
*/
|
*/
|
||||||
if (loader->ctx)
|
if (loader->ctx)
|
||||||
heif_context_free(loader->ctx);
|
heif_context_free_f(loader->ctx);
|
||||||
free(loader_data);
|
free(loader_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,12 +420,61 @@ module_open(Evas_Module *em)
|
||||||
|
|
||||||
em->functions = (void *)(&evas_image_load_heif_func);
|
em->functions = (void *)(&evas_image_load_heif_func);
|
||||||
|
|
||||||
|
#if defined (_WIN32)
|
||||||
|
LOAD("libheif-1.dll");
|
||||||
|
LOAD("libheif.dll");
|
||||||
|
#elif defined (_CYGWIN__)
|
||||||
|
LOAD("cygheif-1.dll");
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
LOAD("libheif.1.dylib");
|
||||||
|
#else
|
||||||
|
LOAD("libheif.so.1");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!_evas_loader_heif_mod)
|
||||||
|
{
|
||||||
|
EINA_LOG_ERR("Can not open libheif shared library.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYM(heif_check_filetype);
|
||||||
|
SYM(heif_context_alloc);
|
||||||
|
SYM(heif_context_free);
|
||||||
|
SYM(heif_context_get_primary_image_handle);
|
||||||
|
SYM(heif_context_read_from_memory_without_copy);
|
||||||
|
SYM(heif_decode_image);
|
||||||
|
SYM(heif_image_get_plane_readonly);
|
||||||
|
SYM(heif_image_handle_get_height);
|
||||||
|
SYM(heif_image_handle_get_width);
|
||||||
|
SYM(heif_image_handle_has_alpha_channel);
|
||||||
|
SYM(heif_image_handle_release);
|
||||||
|
|
||||||
|
heif_init_f = eina_module_symbol_get(_evas_loader_heif_mod, "heif_init");
|
||||||
|
heif_deinit_f = eina_module_symbol_get(_evas_loader_heif_mod, "heif_deinit");
|
||||||
|
|
||||||
|
if (heif_init_f)
|
||||||
|
{
|
||||||
|
heif_init_f(NULL);
|
||||||
|
printf("HEIF !!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
eina_log_domain_unregister(_evas_loader_heif_log_dom);
|
||||||
|
_evas_loader_heif_log_dom = -1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
module_close(Evas_Module *em EINA_UNUSED)
|
module_close(Evas_Module *em EINA_UNUSED)
|
||||||
{
|
{
|
||||||
|
if (heif_deinit_f)
|
||||||
|
heif_deinit_f();
|
||||||
|
|
||||||
|
if (_evas_loader_heif_mod)
|
||||||
|
eina_module_free(_evas_loader_heif_mod);
|
||||||
|
|
||||||
if (_evas_loader_heif_log_dom >= 0)
|
if (_evas_loader_heif_log_dom >= 0)
|
||||||
{
|
{
|
||||||
eina_log_domain_unregister(_evas_loader_heif_log_dom);
|
eina_log_domain_unregister(_evas_loader_heif_log_dom);
|
||||||
|
|
Loading…
Reference in New Issue