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

git pushed a commit to branch libavif-loader
in repository legacy-imlib2.

View the commit online.

commit 203f8c0f486b00569da9feeb2f726ae03dde5034
Author: NRK <n...@disroot.org>
AuthorDate: Wed Feb 26 03:43:12 2025 +0000

    AVIF loader: add new loader based on libavif
    
    supports animated avif unlike the libheif loader.
    can be slow on 'large' animated images though.
    
    Closes: https://git.enlightenment.org/old/legacy-imlib2/issues/28
---
 configure.ac                      |   2 +
 src/lib/loaders.c                 |   6 +++
 src/modules/loaders/Makefile.am   |   9 ++++
 src/modules/loaders/loader_avif.c | 106 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 123 insertions(+)

diff --git a/configure.ac b/configure.ac
index aab3526..533bd34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -215,6 +215,7 @@ loader_check_gif() {
   fi
 }
 
+EC_LOADER_CHECK(AVIF, auto, libavif)
 EC_LOADER_CHECK(GIF,  auto, , loader_check_gif)
 EC_LOADER_CHECK(HEIF, auto, libheif)
 EC_LOADER_CHECK(JPEG, auto, libjpeg)
@@ -313,6 +314,7 @@ echo "Configuration Options Summary:"
 echo
 echo "Image loaders:"
 echo " Regular image loaders"
+echo "  AVIF....................: $avif_ok"
 echo "  GIF.....................: $gif_ok"
 echo "  HEIF....................: $heif_ok"
 echo "  JPEG....................: $jpeg_ok"
diff --git a/src/lib/loaders.c b/src/lib/loaders.c
index 9a3559d..0086b4f 100644
--- a/src/lib/loaders.c
+++ b/src/lib/loaders.c
@@ -25,6 +25,9 @@ typedef struct {
 
 static const char *const ext_ani[] = { "ani", NULL };
 static const char *const ext_argb[] = { "argb", NULL };
+#ifdef BUILD_AVIF_LOADER
+static const char *const ext_avif[] = { "avif", "avifs", NULL };
+#endif
 static const char *const ext_bmp[] = { "bmp", NULL };
 static const char *const ext_ff[] = { "ff", NULL };
 #ifdef BUILD_GIF_LOADER
@@ -92,6 +95,9 @@ static const char *const ext_id3[] = { "mp3", NULL };
 static const KnownLoader loaders_known[] = {
     { "ani", ext_ani },
     { "argb", ext_argb },
+#ifdef BUILD_AVIF_LOADER
+    { "avif", ext_avif },
+#endif
     { "bmp", ext_bmp },
     { "ff", ext_ff },
 #ifdef BUILD_GIF_LOADER
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am
index d5752ce..f186904 100644
--- a/src/modules/loaders/Makefile.am
+++ b/src/modules/loaders/Makefile.am
@@ -17,6 +17,9 @@ tga.la \
 xbm.la \
 xpm.la
 
+if BUILD_AVIF_LOADER
+pkg_LTLIBRARIES += avif.la
+endif
 if BUILD_GIF_LOADER
 pkg_LTLIBRARIES += gif.la
 endif
@@ -81,6 +84,12 @@ argb_la_LDFLAGS      = -module -avoid-version
 argb_la_LIBADD       = $(top_builddir)/src/lib/libImlib2.la
 argb_la_LIBTOOLFLAGS = --tag=disable-static
 
+avif_la_SOURCES       = loader_avif.c
+avif_la_CPPFLAGS      = $(AM_CPPFLAGS) $(AVIF_CFLAGS)
+avif_la_LDFLAGS       = -module -avoid-version
+avif_la_LIBADD        = $(AVIF_LIBS) $(top_builddir)/src/lib/libImlib2.la
+avif_la_LIBTOOLFLAGS  = --tag=disable-static
+
 bmp_la_SOURCES       = loader_bmp.c
 bmp_la_LDFLAGS       = -module -avoid-version
 bmp_la_LIBADD        = $(top_builddir)/src/lib/libImlib2.la
diff --git a/src/modules/loaders/loader_avif.c b/src/modules/loaders/loader_avif.c
new file mode 100644
index 0000000..3838c13
--- /dev/null
+++ b/src/modules/loaders/loader_avif.c
@@ -0,0 +1,106 @@
+#include "config.h"
+#include "Imlib2_Loader.h"
+
+#include <avif/avif.h>
+
+#define DBG_PFX "LDR-avif"
+#define MAX_THREADS 4
+
+static const char *const _formats[] = { "avif", "avifs" };
+
+static int
+_load(ImlibImage *im, int load_data)
+{
+    avifDecoder      *dec;
+    avifRGBImage      rgb;
+    avifImageTiming   timing;
+    int               rc;
+    int               frame, fcount;
+    ImlibImageFrame  *pf;
+
+    dec = avifDecoderCreate();
+    if (!dec)
+        return LOAD_OOM;
+    dec->maxThreads = MAX_THREADS;
+
+    if (avifDecoderSetIOMemory(dec, im->fi->fdata, im->fi->fsize) != AVIF_RESULT_OK)
+        QUIT_WITH_RC(LOAD_OOM);
+
+    switch (avifDecoderParse(dec))
+    {
+        case AVIF_RESULT_OK:
+            break;
+        case AVIF_RESULT_OUT_OF_MEMORY:
+            QUIT_WITH_RC(LOAD_OOM);
+            break;
+        default:
+            QUIT_WITH_RC(LOAD_FAIL);
+            break;
+    }
+
+    im->w = dec->image->width;
+    im->h = dec->image->height;
+    im->has_alpha = dec->alphaPresent;
+    if (!IMAGE_DIMENSIONS_OK(im->w, im->h))
+        QUIT_WITH_RC(LOAD_BADIMAGE);
+
+    pf = NULL;
+    frame = im->frame;
+    if (frame > 0)
+    {
+        fcount = dec->imageCount;
+        if (frame > 1 && frame > fcount)
+            QUIT_WITH_RC(LOAD_BADFRAME);
+
+        pf = __imlib_GetFrame(im);
+        if (!pf)
+            QUIT_WITH_RC(LOAD_OOM);
+        pf->frame_count = fcount;
+        pf->loop_count = 0; /* loop forever */
+        if (pf->frame_count > 1)
+            pf->frame_flags |= FF_IMAGE_ANIMATED;
+        pf->canvas_w = dec->image->width;
+        pf->canvas_h = dec->image->height;
+
+        if (avifDecoderNthImageTiming(dec, frame - 1, &timing) != AVIF_RESULT_OK)
+            QUIT_WITH_RC(LOAD_BADIMAGE);
+        pf->frame_delay = (int)(timing.duration * 1000);
+    }
+    else
+    {
+        frame = 1;
+    }
+
+    if (!load_data)
+        QUIT_WITH_RC(LOAD_SUCCESS);
+
+    if (avifDecoderNthImage(dec, frame - 1) != AVIF_RESULT_OK)
+        QUIT_WITH_RC(LOAD_BADIMAGE);
+
+    if (!__imlib_AllocateData(im))
+        QUIT_WITH_RC(LOAD_OOM);
+
+    avifRGBImageSetDefaults(&rgb, dec->image);
+    rgb.depth = 8;
+    rgb.pixels = (uint8_t *)im->data;
+    rgb.rowBytes = im->w * 4;
+    rgb.maxThreads = MAX_THREADS;
+#ifdef WORDS_BIGENDIAN /* NOTE(NRK): untested on big endian */
+    rgb.format = AVIF_RGB_FORMAT_ARGB;
+#else
+    rgb.format = AVIF_RGB_FORMAT_BGRA;
+#endif
+    /* NOTE(NRK): shouldn't fail, i think. check anyways. */
+    if (avifImageYUVToRGB(dec->image, &rgb) != AVIF_RESULT_OK)
+        QUIT_WITH_RC(LOAD_BADIMAGE);
+
+    if (im->lc)
+        __imlib_LoadProgressRows(im, 0, im->h);
+    rc = LOAD_SUCCESS;
+
+quit:
+    avifDecoderDestroy(dec);
+    return rc;
+}
+
+IMLIB_LOADER(_formats, _load, NULL);

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

Reply via email to