Commit bd114ed6 for libheif

commit bd114ed6d592adc92a09882172ab71d1b4c6e1b1
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Fri May 29 17:28:58 2026 +0200

    factor out LIBHEIF_API macro into heif_export.h

    The LIBHEIF_API export macro previously lived in heif_library.h, which
    made heif_error.h non-self-contained: it uses LIBHEIF_API but cannot
    include heif_library.h, because the two headers are mutually dependent
    (heif_library.h needs the heif_error type).

    Move the macro into a tiny, dependency-free heif_export.h and include it
    from both headers. Every public header now compiles standalone as plain
    C, so the heif_error.h prelude exception in check-c-headers.sh is removed.

    Also fill in the API versions table in heif_library.h with the 1.21,
    1.22, and 1.23 rows.

diff --git a/libheif/CMakeLists.txt b/libheif/CMakeLists.txt
index f104f33c..6f6bda27 100644
--- a/libheif/CMakeLists.txt
+++ b/libheif/CMakeLists.txt
@@ -4,6 +4,7 @@ configure_file(api/libheif/heif_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/heif_ve

 set(libheif_headers
         api/libheif/heif.h
+        api/libheif/heif_export.h
         api/libheif/heif_library.h
         api/libheif/heif_image.h
         api/libheif/heif_color.h
diff --git a/libheif/api/libheif/heif_error.h b/libheif/api/libheif/heif_error.h
index c0de48f1..06565f02 100644
--- a/libheif/api/libheif/heif_error.h
+++ b/libheif/api/libheif/heif_error.h
@@ -28,6 +28,8 @@ extern "C" {
 #include <stddef.h>
 #include <stdint.h>

+#include <libheif/heif_export.h>
+

 typedef enum heif_error_code
 {
diff --git a/libheif/api/libheif/heif_export.h b/libheif/api/libheif/heif_export.h
new file mode 100644
index 00000000..720a12ee
--- /dev/null
+++ b/libheif/api/libheif/heif_export.h
@@ -0,0 +1,48 @@
+/*
+ * HEIF codec.
+ * Copyright (c) 2017-2026 Dirk Farin <dirk.farin@gmail.com>
+ *
+ * This file is part of libheif.
+ *
+ * libheif is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * libheif is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libheif.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBHEIF_HEIF_EXPORT_H
+#define LIBHEIF_HEIF_EXPORT_H
+
+// LIBHEIF_API marks the symbols that are exported from the shared library.
+//
+// This macro lives in its own tiny, dependency-free header so that every
+// public header can pull it in without creating include cycles. In particular,
+// heif_library.h and heif_error.h are mutually dependent (heif_library.h needs
+// the heif_error type while heif_error.h needs LIBHEIF_API), so the macro
+// cannot live in either of them if both are to compile standalone.
+
+#if (defined(_WIN32) || defined __CYGWIN__) && !defined(LIBHEIF_STATIC_BUILD)
+#ifdef LIBHEIF_EXPORTS
+#define LIBHEIF_API __declspec(dllexport)
+#else
+#define LIBHEIF_API __declspec(dllimport)
+#endif
+#elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+#ifdef LIBHEIF_EXPORTS
+#define LIBHEIF_API __attribute__((__visibility__("default")))
+#else
+#define LIBHEIF_API
+#endif
+#else
+#define LIBHEIF_API
+#endif
+
+#endif  // LIBHEIF_HEIF_EXPORT_H
diff --git a/libheif/api/libheif/heif_library.h b/libheif/api/libheif/heif_library.h
index 73610aa0..ee7c1c50 100644
--- a/libheif/api/libheif/heif_library.h
+++ b/libheif/api/libheif/heif_library.h
@@ -48,28 +48,14 @@ extern "C" {
 //  1.18           5            7             1             1            1            1
 //  1.19           6            7             2             1            1            1
 //  1.20           7            7             2             1            1            1
-
-// TODO (v1.23.0): factor the LIBHEIF_API export macro out into its own tiny,
-// dependency-free header (e.g. heif_export.h) and include it from both this
-// header and heif_error.h. Currently heif_error.h is not self-contained: it
-// uses LIBHEIF_API but cannot include heif_library.h because the two headers
-// are mutually dependent (heif_library.h needs the heif_error type). Breaking
-// this cycle would let every public header compile standalone as C.
-#if (defined(_WIN32) || defined __CYGWIN__) && !defined(LIBHEIF_STATIC_BUILD)
-#ifdef LIBHEIF_EXPORTS
-#define LIBHEIF_API __declspec(dllexport)
-#else
-#define LIBHEIF_API __declspec(dllimport)
-#endif
-#elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
-#ifdef LIBHEIF_EXPORTS
-#define LIBHEIF_API __attribute__((__visibility__("default")))
-#else
-#define LIBHEIF_API
-#endif
-#else
-#define LIBHEIF_API
-#endif
+//  1.21           8            7             2             1            1            1
+//  1.22           9            8             2             1            1            1
+//  1.23          10            8             2             1            1            1
+
+// The LIBHEIF_API export macro is defined in its own dependency-free header so
+// that heif_error.h (which is needed by this header) can use it without
+// creating an include cycle.
+#include <libheif/heif_export.h>

 /**
  * Build a 32 bit integer from a 4-character code.
diff --git a/scripts/check-c-headers.sh b/scripts/check-c-headers.sh
index ccba67c6..ff38f3f6 100755
--- a/scripts/check-c-headers.sh
+++ b/scripts/check-c-headers.sh
@@ -31,14 +31,6 @@ set -e
 # catching C++-isms, testing headers independently also verifies they are
 # self-contained (pull in their own dependencies). Any header that fails to
 # parse as C is reported and the script exits non-zero.
-#
-# Exception: heif_error.h is currently NOT self-contained -- it uses the
-# LIBHEIF_API macro but cannot include heif_library.h, because the two headers
-# are mutually dependent. It is therefore tested with the <libheif/heif.h>
-# umbrella prelude instead of standalone.
-# TODO (v1.23.0): once the LIBHEIF_API macro is factored out into its own
-# dependency-free header (see the TODO in heif_library.h), remove this
-# exception so heif_error.h is checked standalone like every other header.

 ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)"
 API_DIR="$ROOT/libheif/api/libheif"
@@ -47,8 +39,8 @@ API_DIR="$ROOT/libheif/api/libheif"
 CXX_ONLY="heif_cxx.h heif_emscripten.h"

 # Headers that are not (yet) self-contained and must be tested with the
-# <libheif/heif.h> umbrella prelude instead of standalone. See the TODO above.
-NEEDS_PRELUDE="heif_error.h"
+# <libheif/heif.h> umbrella prelude instead of standalone.
+NEEDS_PRELUDE=""

 # C standards to validate against. C99 is intentionally excluded: the headers
 # legitimately repeat identical typedefs (e.g. heif_image_handle), which C11