This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch devs/devilhorns/apos
in repository efl.

View the commit online.

commit 84a0f83d703c21c13c788b594abba7f591d009ef
Author: Vincent Torri <vto...@outlook.fr>
AuthorDate: Mon May 1 18:12:28 2023 +0200

    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.
---
 src/lib/evas/meson.build                           |   2 +-
 .../evas/image_loaders/heif/evas_image_load_heif.c | 172 ++++++++++++++++++---
 2 files changed, 151 insertions(+), 23 deletions(-)

diff --git a/src/lib/evas/meson.build b/src/lib/evas/meson.build
index b68bc04451..38e9e250a1 100644
--- a/src/lib/evas/meson.build
+++ b/src/lib/evas/meson.build
@@ -21,7 +21,7 @@ evas_image_loaders_file = [
      ['eet',     'static', [eet]],
      ['generic', 'shared', [rt]],
      ['gif',     'shared', [giflib]],
-     ['heif',    'shared', [heif]],
+     ['heif',    'shared', []],
      ['ico',     'shared', []],
      ['jpeg',    'static', [jpeg]],
      ['jp2k',    'shared', [libopenjp2]],
diff --git a/src/modules/evas/image_loaders/heif/evas_image_load_heif.c b/src/modules/evas/image_loaders/heif/evas_image_load_heif.c
index d103ef2081..e5e2234aee 100644
--- a/src/modules/evas/image_loaders/heif/evas_image_load_heif.c
+++ b/src/modules/evas/image_loaders/heif/evas_image_load_heif.c
@@ -16,6 +16,86 @@ struct _Evas_Loader_Internal
 };
 
 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
 # 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 */
    if ((length < 12) ||
-       (heif_check_filetype(map, length) == heif_filetype_no))
+       (heif_check_filetype_f(map, length) == heif_filetype_no))
      {
         INF("HEIF header invalid");
         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
         return ret;
      }
 
-   ctx = heif_context_alloc();
+   ctx = heif_context_alloc_f();
    if (!ctx)
      {
         INF("cannot allocate heif_context");
@@ -60,7 +140,7 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
         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)
      {
         INF("%s", err.message);
@@ -68,7 +148,7 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
         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)
      {
         INF("%s", err.message);
@@ -76,8 +156,8 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
         goto free_ctx;
      }
 
-   prop->w = heif_image_handle_get_width(handle);
-   prop->h = heif_image_handle_get_height(handle);
+   prop->w = heif_image_handle_get_width_f(handle);
+   prop->h = heif_image_handle_get_height_f(handle);
 
    /* if size is invalid, we exit */
    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;
      }
 
-   prop->alpha = !!heif_image_handle_has_alpha_channel(handle);
+   prop->alpha = !!heif_image_handle_has_alpha_channel_f(handle);
 
    *error = EVAS_LOAD_ERROR_NONE;
    ret = EINA_TRUE;
 
  release_handle:
-   heif_image_handle_release(handle);
+   heif_image_handle_release_f(handle);
  free_ctx:
-   heif_context_free(ctx);
+   heif_context_free_f(ctx);
 
    return ret;
 }
@@ -128,7 +208,7 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
    ctx = loader->ctx;
    if (!ctx)
      {
-        ctx = heif_context_alloc();
+        ctx = heif_context_alloc_f();
         if (!ctx)
           {
             INF("cannot allocate heif_context");
@@ -136,33 +216,33 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
             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)
           {
              INF("%s", err.message);
              *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-             heif_context_free(ctx);
+             heif_context_free_f(ctx);
              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)
           {
              INF("%s", err.message);
              *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-             heif_image_handle_release(handle);
-             heif_context_free(ctx);
+             heif_image_handle_release_f(handle);
+             heif_context_free_f(ctx);
              return ret;
           }
 
         loader->ctx = ctx;
      }
 
-   err = heif_decode_image(handle, &img, heif_colorspace_RGB,
-                           prop->alpha ? heif_chroma_interleaved_RGBA
-                                       : heif_chroma_interleaved_RGB,
-                           NULL);
+   err = heif_decode_image_f(handle, &img, heif_colorspace_RGB,
+                             prop->alpha ? heif_chroma_interleaved_RGBA
+                                         : heif_chroma_interleaved_RGB,
+                             NULL);
 
    if (err.code != heif_error_Ok)
      {
@@ -171,7 +251,7 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
         goto on_error;
      }
 
-   data = "" heif_channel_interleaved, &stride);
+   data = "" heif_channel_interleaved, &stride);
 
    dd  = (unsigned char *)pixels;
    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
     */
    if (loader->ctx)
-     heif_context_free(loader->ctx);
+     heif_context_free_f(loader->ctx);
    free(loader_data);
 }
 
@@ -340,12 +420,60 @@ module_open(Evas_Module *em)
 
    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);
+     }
+
    return 1;
+
+ error:
+   eina_log_domain_unregister(_evas_loader_heif_log_dom);
+   _evas_loader_heif_log_dom = -1;
+   return 0;
 }
 
 static void
 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)
      {
         eina_log_domain_unregister(_evas_loader_heif_log_dom);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to