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

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

View the commit online.

commit 68a5af8cb29e73382fe1c475acea008a368c7602
Author: Kim Woelders <[email protected]>
AuthorDate: Sun Dec 4 09:08:57 2022 +0100

    Add new ani loader
---
 src/lib/loaders.c                |   2 +
 src/modules/loaders/Makefile.am  |   6 ++
 src/modules/loaders/loader_ani.c | 139 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)

diff --git a/src/lib/loaders.c b/src/lib/loaders.c
index e871883..293d45d 100644
--- a/src/lib/loaders.c
+++ b/src/lib/loaders.c
@@ -22,6 +22,7 @@ typedef struct {
    const char         *const *ext;
 } KnownLoader;
 
+static const char  *const ext_ani[] = { "ani", NULL };
 static const char  *const ext_argb[] = { "argb", NULL };
 static const char  *const ext_bmp[] = { "bmp", NULL };
 static const char  *const ext_ff[] = { "ff", NULL };
@@ -79,6 +80,7 @@ static const char  *const ext_id3[] = { "mp3", NULL };
 #endif
 
 static const KnownLoader loaders_known[] = {
+   {"ani", ext_ani},
    {"argb", ext_argb},
    {"bmp", ext_bmp},
    {"ff", ext_ff},
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am
index 9f4c44d..eb4b755 100644
--- a/src/modules/loaders/Makefile.am
+++ b/src/modules/loaders/Makefile.am
@@ -4,6 +4,7 @@ AM_CPPFLAGS          = -I$(top_builddir) -I$(top_srcdir)/src/lib
 pkgdir               = $(libdir)/imlib2/loaders
 
 pkg_LTLIBRARIES = \
+ani.la \
 argb.la \
 bmp.la \
 ff.la \
@@ -59,6 +60,11 @@ if BUILD_ID3_LOADER
 pkg_LTLIBRARIES += id3.la
 endif
 
+ani_la_SOURCES       = loader_ani.c
+ani_la_LDFLAGS       = -module -avoid-version
+ani_la_LIBADD        = $(top_builddir)/src/lib/libImlib2.la
+ani_la_LIBTOOLFLAGS  = --tag=disable-static
+
 argb_la_SOURCES      = loader_argb.c
 argb_la_LDFLAGS      = -module -avoid-version
 argb_la_LIBADD       = $(top_builddir)/src/lib/libImlib2.la
diff --git a/src/modules/loaders/loader_ani.c b/src/modules/loaders/loader_ani.c
new file mode 100644
index 0000000..81b17ea
--- /dev/null
+++ b/src/modules/loaders/loader_ani.c
@@ -0,0 +1,139 @@
+/*
+ * ANI loader
+ *
+ * File format:
+ * https://en.wikipedia.org/wiki/Resource_Interchange_File_Format
+ * https://www.daubnet.com/en/file-format-ani
+ */
+#include "config.h"
+#include "Imlib2_Loader.h"
+
+#if IMLIB2_DEBUG
+#define Dx(fmt...) if (__imlib_debug & DBG_LDR) __imlib_printf(NULL, fmt)
+#else
+#define Dx(fmt...)
+#endif
+
+#define DBG_PFX "LDR-ani"
+
+#define T(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 24))
+
+#define RIFF_TYPE_RIFF	T('R', 'I', 'F', 'F')
+#define RIFF_TYPE_LIST	T('L', 'I', 'S', 'T')
+#define RIFF_TYPE_INAM	T('I', 'N', 'A', 'M')
+#define RIFF_TYPE_IART	T('I', 'A', 'R', 'T')
+#define RIFF_TYPE_icon	T('i', 'c', 'o', 'n')
+
+#define RIFF_NAME_ACON	T('A', 'C', 'O', 'N')
+
+static const char  *const _formats[] = { "ani" };
+
+typedef struct {
+   unsigned char       nest;
+} riff_ctx_t;
+
+static int
+_load_embedded(ImlibImage * im, int load_data, const char *data,
+               unsigned int size)
+{
+   int                 rc;
+   ImlibLoader        *loader;
+
+   loader = __imlib_FindBestLoader(NULL, "ico", 0);
+   if (!loader)
+      return LOAD_FAIL;
+
+   rc = __imlib_LoadEmbeddedMem(loader, im, load_data, data, size);
+
+   return rc;
+}
+
+#define LE32(p) (SWAP_LE_32(*((const uint32_t*)(p))))
+#define OFFS(p) ((const char*)(p) - (const char*)im->fi->fdata)
+
+static int
+_riff_parse(ImlibImage * im, riff_ctx_t * ctx, const char *fdata,
+            unsigned int fsize, const char *fptr)
+{
+   int                 rc;
+   unsigned int        type;
+   int                 size, avail;
+
+   rc = LOAD_FAIL;
+   ctx->nest += 1;
+
+   for (; rc == 0; fptr += 8 + size)
+     {
+        avail = fdata + fsize - fptr;   /* Bytes left in chunk */
+
+        if (avail <= 0)
+           break;               /* Normal end (= 0) */
+        if (avail < 8)
+          {
+             D("%5lu: %*s Chunk: %.4s premature end\n",
+               OFFS(fptr), ctx->nest, "", fptr);
+             break;
+          }
+
+        type = LE32(fptr);
+        size = LE32(fptr + 4);
+
+        D("%5lu: %*s Chunk: %.4s size %u: ",
+          OFFS(fptr), ctx->nest, "", fptr, size);
+
+        if (ctx->nest == 1 && fptr == fdata)
+          {
+             Dx("\n");
+             /* First chunk of file */
+             if (type != RIFF_TYPE_RIFF || (LE32(fptr + 8)) != RIFF_NAME_ACON)
+                return LOAD_FAIL;
+             size = 4;
+             continue;
+          }
+
+        if (avail < 8 + size)
+          {
+             Dx("incorrect size\n");
+             rc = LOAD_BADFILE;
+             break;
+          }
+
+        switch (type)
+          {
+          default:
+          case RIFF_TYPE_RIFF:
+             Dx("\n");
+             break;
+          case RIFF_TYPE_INAM:
+          case RIFF_TYPE_IART:
+             Dx("'%.*s'\n", size, fptr + 8);
+             break;
+          case RIFF_TYPE_LIST:
+             Dx("'%.*s'\n", 4, fptr + 8);
+             rc = _riff_parse(im, ctx, fptr + 12, size - 4, fptr + 12);
+             break;
+          case RIFF_TYPE_icon:
+             Dx("\n");
+             rc = _load_embedded(im, 1, fptr + 8, size);
+             break;
+          }
+        size = (size + 1) & ~1;
+     }
+
+   ctx->nest -= 1;
+
+   return rc;
+}
+
+static int
+_load(ImlibImage * im, int load_data)
+{
+   int                 rc;
+   riff_ctx_t          ctx = { };
+
+   rc = _riff_parse(im, &ctx, im->fi->fdata, im->fi->fsize, im->fi->fdata);
+
+   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