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 cffab0e3a9dc4191e5a3f460c4ac09203d2d378f
Author: Vincent Torri <vto...@outlook.fr>
AuthorDate: Thu May 4 12:34:39 2023 +0200

    Evas heif loader: correctly manage stride and alpha
---
 .../evas/image_loaders/heif/evas_image_load_heif.c | 151 +++++++++------------
 1 file changed, 67 insertions(+), 84 deletions(-)

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 e5e2234aee..839866a5d1 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
@@ -13,6 +13,7 @@ struct _Evas_Loader_Internal
    Eina_File *f;
    Evas_Image_Load_Opts *opts;
    struct heif_context* ctx;
+   struct heif_image_handle *handle;
 };
 
 static int _evas_loader_heif_log_dom = -1;
@@ -28,11 +29,11 @@ static Eina_Module *_evas_loader_heif_mod = NULL;
          }                                                  \
     }
 
-#define SYM(x)                                                     \
+#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;                                                  \
+      ERR("Cannot find symbol '%s' in '%s'",                             \
+          #x, eina_module_file_get(_evas_loader_heif_mod));              \
+      goto error;                                                        \
    }
 
 // heif_check_filetype
@@ -108,10 +109,10 @@ static heif_image_handle_release_t heif_image_handle_release_f = NULL;
 #define INF(...) EINA_LOG_DOM_INFO(_evas_loader_heif_log_dom, __VA_ARGS__)
 
 static Eina_Bool
-evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED,
-                                        Emile_Image_Property *prop,
-                                        void *map, size_t length,
-                                        int *error)
+evas_image_load_file_head_heif_init(Evas_Loader_Internal *loader,
+                                    Emile_Image_Property *prop,
+                                    void *map, size_t length,
+                                    int *error)
 {
    struct heif_context *ctx;
    struct heif_image_handle *handle;
@@ -125,7 +126,7 @@ 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_f(map, length) == heif_filetype_no))
+       (heif_check_filetype_f(map, length) != heif_filetype_yes_supported))
      {
         INF("HEIF header invalid");
         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
@@ -145,7 +146,8 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
      {
         INF("%s", err.message);
         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        goto free_ctx;
+        heif_context_free_f(ctx);
+        return ret;
    }
 
    err = heif_context_get_primary_image_handle_f(ctx, &handle);
@@ -153,7 +155,8 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
      {
         INF("%s", err.message);
         *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        goto free_ctx;
+        heif_context_free_f(ctx);
+        return ret;
      }
 
    prop->w = heif_image_handle_get_width_f(handle);
@@ -168,22 +171,37 @@ evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader EINA_UNUSED
           *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
         else
           *error= EVAS_LOAD_ERROR_GENERIC;
-        goto release_handle;
+        heif_image_handle_release_f(handle);
+        heif_context_free_f(ctx);
+        return ret;
      }
 
    prop->alpha = !!heif_image_handle_has_alpha_channel_f(handle);
+   loader->ctx = ctx;
+   loader->handle = handle;
 
    *error = EVAS_LOAD_ERROR_NONE;
    ret = EINA_TRUE;
 
- release_handle:
-   heif_image_handle_release_f(handle);
- free_ctx:
-   heif_context_free_f(ctx);
-
    return ret;
 }
 
+static Eina_Bool
+evas_image_load_file_head_heif_internal(Evas_Loader_Internal *loader,
+                                        Emile_Image_Property *prop,
+                                        void *map, size_t length,
+                                        int *error)
+{
+
+   if (!evas_image_load_file_head_heif_init(loader, prop, map, length, error))
+     return EINA_FALSE;
+
+   heif_image_handle_release_f(loader->handle);
+   heif_context_free_f(loader->ctx);
+
+   return EINA_TRUE;
+}
+
 static Eina_Bool
 evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
                                         Emile_Image_Property *prop,
@@ -191,13 +209,11 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
                                         void *map, size_t length,
                                         int *error)
 {
-   struct heif_context *ctx;
-   struct heif_image_handle *handle;
    struct heif_image *img;
    struct heif_error err;
    const unsigned char *data;
    unsigned char *dd;
-   unsigned char *ds;
+   unsigned char *plane;
    int stride;
    unsigned int x;
    unsigned int y;
@@ -205,41 +221,10 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
 
    ret = EINA_FALSE;
 
-   ctx = loader->ctx;
-   if (!ctx)
-     {
-        ctx = heif_context_alloc_f();
-        if (!ctx)
-          {
-            INF("cannot allocate heif_context");
-            *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-            return ret;
-          }
-
-        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_f(ctx);
-             return ret;
-          }
-
-        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_f(handle);
-             heif_context_free_f(ctx);
-             return ret;
-          }
-
-        loader->ctx = ctx;
-     }
+   if (!evas_image_load_file_head_heif_init(loader, prop, map, length, error))
+     return ret;
 
-   err = heif_decode_image_f(handle, &img, heif_colorspace_RGB,
+   err = heif_decode_image_f(loader->handle, &img, heif_colorspace_RGB,
                              prop->alpha ? heif_chroma_interleaved_RGBA
                                          : heif_chroma_interleaved_RGB,
                              NULL);
@@ -253,37 +238,37 @@ evas_image_load_file_data_heif_internal(Evas_Loader_Internal *loader,
 
    data = "" heif_channel_interleaved, &stride);
 
-   dd  = (unsigned char *)pixels;
-   ds = (unsigned char *)data;
+   dd = (unsigned char *)pixels;
+   plane = (unsigned char *)data;
    if (!prop->alpha)
      {
-       for (y = 0; y < prop->h; y++)
-         {
-           for (x = 0; x < prop->w; x++)
-             {
-               dd[3] = 0xff;
-               dd[0] = ds[2];
-               dd[1] = ds[1];
-               dd[2] = ds[0];
-               ds+=3;
-               dd+=4;
-             }
-         }
+       for (y = 0; y < prop->h; y++, plane += stride)
+          {
+             int from = 0;
+             for (x = 0; x < prop->w; x++, from += 3)
+               {
+                  dd[0] = *(plane + from + 2);
+                  dd[1] = *(plane + from + 1);
+                  dd[2] = *(plane + from + 0);
+                  dd[3] = 0xff;
+                  dd += 4;
+               }
+          }
      }
    else
      {
-       for (y = 0; y < prop->h; y++)
-         {
-           for (x = 0; x < prop->w; x++)
-             {
-               dd[0] = ds[2];
-               dd[1] = ds[1];
-               dd[2] = ds[0];
-               dd[3] = ds[3];
-               ds+=4;
-               dd+=4;
-             }
-         }
+        for (y = 0; y < prop->h; y++, plane += stride)
+          {
+             int from = 0;
+             for (x = 0; x < prop->w; x++, from += 4)
+               {
+                  dd[0] = *(plane + from + 2);
+                  dd[1] = *(plane + from + 1);
+                  dd[2] = *(plane + from + 0);
+                  dd[3] = *(plane + from + 3);
+                  dd += 4;
+               }
+          }
      }
 
    ret = EINA_TRUE;
@@ -323,10 +308,8 @@ evas_image_load_file_close_heif(void *loader_data)
    Evas_Loader_Internal *loader;
 
    loader = loader_data;
-   /*
-    * in case _head() fails (because the file is not an heif one),
-    * loader is not filled and loader->ctx is NULL
-    */
+   if (loader->handle)
+     heif_image_handle_release_f(loader->handle);
    if (loader->ctx)
      heif_context_free_f(loader->ctx);
    free(loader_data);

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

Reply via email to