~exec64/imv-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH imv 1/2] libheif: run library init/deinit routines.

Details
Message ID
<20230602075255.122215-1-alebastr89@gmail.com>
DKIM signature
missing
Download raw message
Patch: +49 -3
A plugin interface[1] added in libheif 1.14.0 requires running
`heif_init` to discover and load the plugins and `heif_deinit` for a
proper cleanup.
To support that, we need to extend the imv_backend structure with
init/uninit callbacks and invoke them when necessary.

Fixes discovery of libheif codecs shipped as dynamic plugins.

[1]: https://github.com/strukturag/libheif#codec-plugins
---
 meson.build           |  2 +-
 src/backend.h         |  8 ++++++++
 src/backend_libheif.c | 24 ++++++++++++++++++++++++
 src/imv.c             | 18 ++++++++++++++++--
 4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/meson.build b/meson.build
index 67ea830..8c59535 100644
--- a/meson.build
+++ b/meson.build
@@ -126,7 +126,7 @@ foreach backend : [
  ['libjpeg', 'dependency', 'libturbojpeg', []],
  ['librsvg', 'dependency', 'librsvg-2.0', '>= 2.44'],
  ['libnsgif', 'dependency', 'libnsgif', []],
  ['libheif', 'dependency', 'libheif', []],
  ['libheif', 'dependency', 'libheif', '>= 1.13.0'],
]
  _backend_name = backend[0]
  _dep_type = backend[1]
diff --git a/src/backend.h b/src/backend.h
index 00fd092..b754a2b 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -46,6 +46,14 @@ struct imv_backend {
   * and src will point to an imv_source instance for the given data.
   */
  enum backend_result (*open_memory)(void *data, size_t len, struct imv_source **src);

  /* Run initialization code before registering the the backend. If successful,
   * BACKEND_SUCCESS is returned.
   */
  enum backend_result (*init)();

  /* Uninitialize backend */
  void (*uninit)();
};

#endif
diff --git a/src/backend_libheif.c b/src/backend_libheif.c
index 8264e87..a020933 100644
--- a/src/backend_libheif.c
+++ b/src/backend_libheif.c
@@ -5,6 +5,7 @@
#include "backend.h"
#include "bitmap.h"
#include "image.h"
#include "log.h"
#include "source_private.h"

struct private {
@@ -54,10 +55,15 @@ struct heif_error get_primary_image(struct heif_context *ctx, struct heif_image
  struct heif_image_handle *handle;
  struct heif_error err = heif_context_get_primary_image_handle(ctx, &handle);
  if (err.code != heif_error_Ok) {
    imv_log(IMV_ERROR, "libheif: failed to get image handle (%s)\n", err.message);
    return err;
  }

  err = heif_decode_image(handle, img, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, NULL);
  if (err.code != heif_error_Ok) {
    imv_log(IMV_ERROR, "libheif: failed to decode image (%s)\n", err.message);
  }

  heif_image_handle_release(handle);
  return err;
}
@@ -109,6 +115,22 @@ static enum backend_result open_memory(void *data, size_t len, struct imv_source
  return BACKEND_SUCCESS;
}

static enum backend_result init()
{
    struct heif_error err = heif_init(NULL);
    if (err.code != heif_error_Ok) {
        imv_log(IMV_ERROR, "libheif: failed to initialize backend (%s)\n", err.message);
        heif_deinit();
        return BACKEND_UNSUPPORTED;
    }
    return BACKEND_SUCCESS;
}

static void uninit()
{
    heif_deinit();
}

const struct imv_backend imv_backend_libheif = {
  .name = "libheif",
  .description = "ISO/IEC 23008-12:2017 HEIF file format decoder and encoder.",
@@ -116,4 +138,6 @@ const struct imv_backend imv_backend_libheif = {
  .license = "GNU Lesser General Public License",
  .open_path = &open_path,
  .open_memory = &open_memory,
  .init = &init,
  .uninit = &uninit,
};
diff --git a/src/imv.c b/src/imv.c
index bca52fd..a7744b2 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -223,6 +223,7 @@ static void render_window(struct imv *imv);
static void update_env_vars(struct imv *imv);
static size_t generate_env_text(struct imv *imv, char *buf, size_t len, const char *format);
static size_t read_from_stdin(void **buffer);
static void imv_backends_free(struct list *backends);

/* Finds the next split between commands in a string (';'). Provides a pointer
 * to the next character after the delimiter as out, or a pointer to '\0' if
@@ -661,7 +662,7 @@ void imv_free(struct imv *imv)
    imv_window_free(imv->window);
  }

  list_free(imv->backends);
  imv_backends_free(imv->backends);

  list_free(imv->startup_commands);

@@ -670,7 +671,20 @@ void imv_free(struct imv *imv)

void imv_install_backend(struct imv *imv, const struct imv_backend *backend)
{
  list_append(imv->backends, (void*)backend);
  if (!backend->init || backend->init() == BACKEND_SUCCESS) {
    list_append(imv->backends, (void*)backend);
  }
}

static void imv_backends_free(struct list *backends)
{
  for (size_t i = 0; i < backends->len; ++i) {
    struct imv_backend *backend = backends->items[i];
    if (backend->uninit) {
      backend->uninit();
    }
  }
  list_free(backends);
}

static bool parse_bg(struct imv *imv, const char *bg)
-- 
2.40.1

[PATCH imv 2/2] libheif: fix handling of odd image sizes

Details
Message ID
<20230602075255.122215-2-alebastr89@gmail.com>
In-Reply-To
<20230602075255.122215-1-alebastr89@gmail.com> (view parent)
DKIM signature
missing
Download raw message
Patch: +10 -1
HEIC requires image sizes to be a multiple of 2 and AVIF wants the sizes
to be a multiple of 8, 16 or 32. libheif addresses that by rounding up
the stride and reporting a cropped box with actual image size that does
not reflect the internal plane layout.
As a result, imv reads few extra pixels for each line and renders a
distorted image (see odd-width cases in the test set).

The naive approach implemented here copies the bitmap line by line,
using the image width and taking stride into account.
A more correct solution would be storing stride for the imv_bitmap and
using it to calculate the value for `GL_UNPACK_ROW_LENGTH`, but it
requires more changes across the whole codebase than I'm willing to do.

Tested with libheif 1.16.1 and <https://github.com/link-u/avif-sample-images>.
---
 src/backend_libheif.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/backend_libheif.c b/src/backend_libheif.c
index a020933..254c7bc 100644
--- a/src/backend_libheif.c
+++ b/src/backend_libheif.c
@@ -35,7 +35,16 @@ static void load_image(void *raw_private, struct imv_image **image, int *frameti
  int width = heif_image_get_width(private->img, heif_channel_interleaved);
  int height = heif_image_get_height(private->img, heif_channel_interleaved);
  unsigned char *bitmap = malloc(width * height * 4);
  memcpy(bitmap, data, width * height * 4);
  if (stride == width * 4) {
    memcpy(bitmap, data, width * height * 4);
  } else {
    unsigned char *ptr = bitmap;

    for (int i = 0; i < height; ++i) {
      memcpy(ptr, data + stride * i, width * 4);
      ptr += width * 4;
    }
  }

  struct imv_bitmap *bmp = malloc(sizeof *bmp);
  bmp->width = width,
-- 
2.40.1

[imv/patches] build failed

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CT206TN6YE1K.165QQDDP2CL1E@cirno2>
In-Reply-To
<20230602075255.122215-2-alebastr89@gmail.com> (view parent)
DKIM signature
missing
Download raw message
imv/patches: FAILED in 4m50s

[libheif: run library init/deinit routines.][0] from [Aleksei Bavshin][1]

[0]: https://lists.sr.ht/~exec64/imv-devel/patches/41580
[1]: alebastr89@gmail.com

✓ #1000071 SUCCESS imv/patches/debian.yml    https://builds.sr.ht/~exec64/job/1000071
✓ #1000069 SUCCESS imv/patches/freebsd.yml   https://builds.sr.ht/~exec64/job/1000069
✓ #1000072 SUCCESS imv/patches/archlinux.yml https://builds.sr.ht/~exec64/job/1000072
✗ #1000070 FAILED  imv/patches/ubuntu.yml    https://builds.sr.ht/~exec64/job/1000070

Re: [imv/patches] build failed

Details
Message ID
<2bfb7473-a084-217e-85c6-0097a7884264@gmail.com>
In-Reply-To
<CT206TN6YE1K.165QQDDP2CL1E@cirno2> (view parent)
DKIM signature
missing
Download raw message
On 6/2/23 00:58, builds.sr.ht wrote:
> imv/patches: FAILED in 4m50s
> 
> [libheif: run library init/deinit routines.][0] from [Aleksei Bavshin][1]
> 
> [0]: https://lists.sr.ht/~exec64/imv-devel/patches/41580
> [1]: alebastr89@gmail.com
> 
> ✓ #1000071 SUCCESS imv/patches/debian.yml    https://builds.sr.ht/~exec64/job/1000071
> ✓ #1000069 SUCCESS imv/patches/freebsd.yml   https://builds.sr.ht/~exec64/job/1000069
> ✓ #1000072 SUCCESS imv/patches/archlinux.yml https://builds.sr.ht/~exec64/job/1000072
> ✗ #1000070 FAILED  imv/patches/ubuntu.yml    https://builds.sr.ht/~exec64/job/1000070

Hm, I haven't checked the release date for 1.13.0. Apparently, it's too 
new to be in Ubuntu LTS :(

Fixup and cleanup of unneeded function:

diff --git a/meson.build b/meson.build
index 8c59535..67ea830 100644
--- a/meson.build
+++ b/meson.build
@@ -126,7 +126,7 @@ foreach backend : [
    ['libjpeg', 'dependency', 'libturbojpeg', []],
    ['librsvg', 'dependency', 'librsvg-2.0', '>= 2.44'],
    ['libnsgif', 'dependency', 'libnsgif', []],
-  ['libheif', 'dependency', 'libheif', '>= 1.13.0'],
+  ['libheif', 'dependency', 'libheif', []],
  ]
    _backend_name = backend[0]
    _dep_type = backend[1]
diff --git a/src/backend_libheif.c b/src/backend_libheif.c
index 254c7bc..26c4313 100644
--- a/src/backend_libheif.c
+++ b/src/backend_libheif.c
@@ -124,6 +124,8 @@ static enum backend_result open_memory(void *data, 
size_t len, struct imv_source
    return BACKEND_SUCCESS;
  }

+#if LIBHEIF_HAVE_VERSION(1,13,0)
+
  static enum backend_result init()
  {
      struct heif_error err = heif_init(NULL);
@@ -135,10 +137,7 @@ static enum backend_result init()
      return BACKEND_SUCCESS;
  }

-static void uninit()
-{
-    heif_deinit();
-}
+#endif

  const struct imv_backend imv_backend_libheif = {
    .name = "libheif",
@@ -147,6 +146,8 @@ const struct imv_backend imv_backend_libheif = {
    .license = "GNU Lesser General Public License",
    .open_path = &open_path,
    .open_memory = &open_memory,
+#if LIBHEIF_HAVE_VERSION(1,13,0)
    .init = &init,
-  .uninit = &uninit,
+  .uninit = &heif_deinit,
+#endif
  };

-- 
With best regards,
Aleksei Bavshin
Reply to thread Export thread (mbox)