Commit efb048c2 for libheif
commit efb048c25e583655496e47a52eb9eb283a5be8da
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Mon Sep 21 18:47:06 2026 +0200
FFmpeg decoder plugin: do not reference the exported heif_error_success object (#1854)
Dynamic plugins are compiled with LIBHEIF_EXPORTS, so inside plugin code
LIBHEIF_API expands to __declspec(dllexport) on MSVC. Exported functions
still resolve through the import library's jump thunks, but exported data
has no thunk, and the reference to heif_error_success in the FFmpeg decoder
and in nalu_utils.cc fails to link when the decoder is built as a plugin.
On Linux this went unnoticed because the loader resolves the symbol from
libheif at dlopen time.
Use a file-local success object instead, as the other plugins do.
nalu_utils.cc is compiled into both libheif and the plugin, so it gets its
own local object rather than depending on heif_plugin.h.
Fixes #1854
diff --git a/libheif/plugins/decoder_ffmpeg.cc b/libheif/plugins/decoder_ffmpeg.cc
index 58634ec1..27fcac48 100644
--- a/libheif/plugins/decoder_ffmpeg.cc
+++ b/libheif/plugins/decoder_ffmpeg.cc
@@ -42,6 +42,11 @@ extern "C"
}
+// Plugins are compiled with LIBHEIF_EXPORTS, so on MSVC a reference to the exported
+// data object heif_error_success does not resolve against libheif (issue #1854).
+// Use a file-local success object instead.
+static const heif_error kSuccess = {heif_error_Ok, heif_suberror_Unspecified, "Success"};
+
struct ffmpeg_decoder
{
// --- input data
@@ -198,7 +203,7 @@ static heif_error ffmpeg_new_decoder2(void** dec, const heif_decoder_plugin_opti
}
- return heif_error_success;
+ return kSuccess;
}
static heif_error ffmpeg_new_decoder(void** dec)
@@ -333,7 +338,7 @@ static heif_error ffmpeg_push_data2(void *decoder_raw, const void *data, size_t
decoder->input_data.emplace_back(std::move(pkt));
- return heif_error_success;
+ return kSuccess;
}
static heif_error ffmpeg_push_data(void *decoder_raw, const void *data, size_t size)
@@ -607,7 +612,7 @@ static heif_error ffmpeg_av_decode(ffmpeg_decoder* decoder, AVCodecContext* av_d
av_frame->width, av_frame->height, shift, byte_swap);
}
- return heif_error_success;
+ return kSuccess;
}
heif_chroma chroma = ffmpeg_get_chroma_format(pix_fmt);
@@ -680,7 +685,7 @@ static heif_error ffmpeg_av_decode(ffmpeg_decoder* decoder, AVCodecContext* av_d
w, h, shift, byte_swap);
}
- return heif_error_success;
+ return kSuccess;
}
else {
const char* fmt_name = av_get_pix_fmt_name(static_cast<AVPixelFormat>(av_frame->format));
@@ -707,7 +712,7 @@ static heif_error ffmpeg_decode_next_image2(void* decoder_raw,
heif_color_profile_nclx* nclx = NULL;
int ret = 0;
- heif_error err = heif_error_success;
+ heif_error err = kSuccess;
if (!decoder->input_data.empty()) {
uint8_t* parse_av_data = NULL;
diff --git a/libheif/plugins/nalu_utils.cc b/libheif/plugins/nalu_utils.cc
index f4f3731d..b5369dde 100644
--- a/libheif/plugins/nalu_utils.cc
+++ b/libheif/plugins/nalu_utils.cc
@@ -23,6 +23,11 @@
#include <utility>
#include "nalu_utils.h"
+// Plugins are compiled with LIBHEIF_EXPORTS, so on MSVC a reference to the exported
+// data object heif_error_success does not resolve against libheif (issue #1854).
+// Use a file-local success object instead.
+static const heif_error kSuccess = {heif_error_Ok, heif_suberror_Unspecified, "Success"};
+
NalUnit::NalUnit()
{
nal_data_ptr = NULL;
@@ -91,7 +96,7 @@ const heif_error NalMap::parseHevcNalu(const uint8_t *cdata, size_t size)
ptr += nal_size;
}
- return heif_error_success;
+ return kSuccess;
}
void NalMap::clear() { map.clear(); }
\ No newline at end of file