Commit 0af3fe26 for libheif

commit 0af3fe269562e8712549ea97ebfe14692a4136fa
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Mon Apr 13 13:54:43 2026 +0200

    use a separate encoder instance for encoding the alpha image (#1732)

diff --git a/libheif/context.cc b/libheif/context.cc
index f0ac28b8..3d152d64 100644
--- a/libheif/context.cc
+++ b/libheif/context.cc
@@ -98,6 +98,53 @@ heif_error heif_encoder::alloc()
 }


+static void copy_encoder_parameters(heif_encoder* dst, const heif_encoder* src)
+{
+  const auto* plugin = src->plugin;
+
+  // Copy dedicated quality/lossless/logging parameters
+  int ival;
+  plugin->get_parameter_quality(src->encoder, &ival);
+  plugin->set_parameter_quality(dst->encoder, ival);
+
+  plugin->get_parameter_lossless(src->encoder, &ival);
+  plugin->set_parameter_lossless(dst->encoder, ival);
+
+  if (plugin->get_parameter_logging_level && plugin->set_parameter_logging_level) {
+    plugin->get_parameter_logging_level(src->encoder, &ival);
+    plugin->set_parameter_logging_level(dst->encoder, ival);
+  }
+
+  // Copy all enumerable plugin parameters
+  const heif_encoder_parameter* const* params = plugin->list_parameters(src->encoder);
+  if (!params) return;
+
+  for (; *params; params++) {
+    const char* name = (*params)->name;
+    switch ((*params)->type) {
+      case heif_encoder_parameter_type_integer: {
+        int v;
+        if (plugin->get_parameter_integer(src->encoder, name, &v).code == heif_error_Ok)
+          plugin->set_parameter_integer(dst->encoder, name, v);
+        break;
+      }
+      case heif_encoder_parameter_type_boolean: {
+        int v;
+        if (plugin->get_parameter_boolean(src->encoder, name, &v).code == heif_error_Ok)
+          plugin->set_parameter_boolean(dst->encoder, name, v);
+        break;
+      }
+      case heif_encoder_parameter_type_string: {
+        char v[256];
+        if (plugin->get_parameter_string(src->encoder, name, v, sizeof(v)).code == heif_error_Ok)
+          plugin->set_parameter_string(dst->encoder, name, v);
+        break;
+      }
+    }
+  }
+}
+
+
 HeifContext::HeifContext()
     : m_memory_tracker(&m_limits)
 {
@@ -1589,9 +1636,17 @@ Result<std::shared_ptr<ImageItem>> HeifContext::encode_image(const std::shared_p
     alpha_image = *alpha_image_result;


-    // --- encode the alpha image
+    // --- encode the alpha image using a fresh encoder instance to avoid
+    //     leaking codec state from the color encoding pass
+
+    heif_encoder alpha_enc(encoder->plugin);
+    heif_error alloc_err = alpha_enc.alloc();
+    if (alloc_err.code) {
+      return Error(alloc_err.code, alloc_err.subcode, alloc_err.message);
+    }
+    copy_encoder_parameters(&alpha_enc, encoder);

-    auto alphaEncodingResult = encode_image(alpha_image, encoder, options,
+    auto alphaEncodingResult = encode_image(alpha_image, &alpha_enc, options,
                          heif_image_input_class_alpha);
     if (!alphaEncodingResult) {
       return alphaEncodingResult.error();