Commit f5eeceaa for libheif
commit f5eeceaa4c6c3357d80ba4080a5d35816484e9f6
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Thu May 28 12:55:06 2026 +0200
add public API for ambient_viewing_environment (amve box)
diff --git a/libheif/api/libheif/heif_color.cc b/libheif/api/libheif/heif_color.cc
index 86b563d3..37ad2854 100644
--- a/libheif/api/libheif/heif_color.cc
+++ b/libheif/api/libheif/heif_color.cc
@@ -530,6 +530,65 @@ void heif_image_handle_set_mastering_display_colour_volume(const heif_image_hand
}
+// --- ambient viewing environment ---
+
+int heif_image_has_ambient_viewing_environment(const heif_image* image)
+{
+ return image->image->has_amve();
+}
+
+
+int heif_image_handle_has_ambient_viewing_environment(const heif_image_handle* handle)
+{
+ return handle->image->get_property<Box_amve>() ? 1 : 0;
+}
+
+
+int heif_image_get_ambient_viewing_environment(const heif_image* image, heif_ambient_viewing_environment* out)
+{
+ if (!image->image->has_amve()) {
+ return 0;
+ }
+
+ if (out) {
+ *out = image->image->get_amve();
+ }
+
+ return 1;
+}
+
+
+int heif_image_handle_get_ambient_viewing_environment(const heif_image_handle* handle, heif_ambient_viewing_environment* out)
+{
+ auto amve = handle->image->get_property<Box_amve>();
+ if (out && amve) {
+ *out = amve->amve;
+ }
+
+ return amve ? 1 : 0;
+}
+
+
+void heif_image_set_ambient_viewing_environment(const heif_image* image, const heif_ambient_viewing_environment* in)
+{
+ if (in == nullptr) {
+ return;
+ }
+
+ image->image->set_amve(*in);
+}
+
+
+void heif_image_handle_set_ambient_viewing_environment(const heif_image_handle* handle, const heif_ambient_viewing_environment* in)
+{
+ if (in == nullptr) {
+ return;
+ }
+
+ handle->image->set_amve(*in);
+}
+
+
// --- nominal diffuse white ---
diff --git a/libheif/api/libheif/heif_color.h b/libheif/api/libheif/heif_color.h
index 64e40f7b..5321b727 100644
--- a/libheif/api/libheif/heif_color.h
+++ b/libheif/api/libheif/heif_color.h
@@ -356,6 +356,29 @@ LIBHEIF_API
void heif_image_handle_set_mastering_display_colour_volume(const heif_image_handle*, const heif_mastering_display_colour_volume* in);
+// --- ambient viewing environment ---
+
+LIBHEIF_API
+int heif_image_has_ambient_viewing_environment(const heif_image*);
+
+LIBHEIF_API
+int heif_image_handle_has_ambient_viewing_environment(const heif_image_handle*);
+
+// Returns whether the image has 'ambient viewing environment' information. If 0 is returned, the output is not filled.
+LIBHEIF_API
+int heif_image_get_ambient_viewing_environment(const heif_image*, heif_ambient_viewing_environment* out);
+
+// Returns whether the image has 'ambient viewing environment' information. If 0 is returned, the output is not filled.
+LIBHEIF_API
+int heif_image_handle_get_ambient_viewing_environment(const heif_image_handle*, heif_ambient_viewing_environment* out);
+
+LIBHEIF_API
+void heif_image_set_ambient_viewing_environment(const heif_image*, const heif_ambient_viewing_environment* in);
+
+LIBHEIF_API
+void heif_image_handle_set_ambient_viewing_environment(const heif_image_handle*, const heif_ambient_viewing_environment* in);
+
+
// --- nominal diffuse white ---
// Nominal diffuse white luminance (ISO/IEC 23008-12 'ndwt' box). The luminance
diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc
index 9479c175..c0e50185 100644
--- a/libheif/image-items/image_item.cc
+++ b/libheif/image-items/image_item.cc
@@ -838,6 +838,13 @@ void ImageItem::set_mdcv(const heif_mastering_display_colour_volume& mdcv)
}
+void ImageItem::set_amve(const heif_ambient_viewing_environment& amve)
+{
+ ImageDescription::set_amve(amve);
+ add_property(create_amve_box(), false);
+}
+
+
void ImageItem::set_nominal_diffuse_white_luminance(uint32_t luminance)
{
ImageDescription::set_nominal_diffuse_white_luminance(luminance);
@@ -1165,6 +1172,13 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const heif_decod
img->set_mdcv(mdcv->mdcv);
}
+ // AMVE
+
+ auto amve = get_property<Box_amve>();
+ if (amve) {
+ img->set_amve(amve->amve);
+ }
+
// NDWT
auto ndwt = get_property<Box_ndwt>();
diff --git a/libheif/image-items/image_item.h b/libheif/image-items/image_item.h
index 91faf1c7..5444ad89 100644
--- a/libheif/image-items/image_item.h
+++ b/libheif/image-items/image_item.h
@@ -329,6 +329,8 @@ public:
void set_mdcv(const heif_mastering_display_colour_volume& mdcv) override;
+ void set_amve(const heif_ambient_viewing_environment& amve) override;
+
void set_nominal_diffuse_white_luminance(uint32_t luminance) override;
void set_pixel_ratio(uint32_t h, uint32_t v) override;
diff --git a/libheif/image/image_description.cc b/libheif/image/image_description.cc
index 7e19bac0..437a68b3 100644
--- a/libheif/image/image_description.cc
+++ b/libheif/image/image_description.cc
@@ -130,6 +130,7 @@ void ImageDescription::copy_metadata_from(const ImageDescription& other)
m_clli = other.m_clli;
m_mdcv = other.m_mdcv;
+ m_amve = other.m_amve;
m_nominal_diffuse_white_luminance = other.m_nominal_diffuse_white_luminance;
heif_tai_timestamp_packet_release(m_tai_timestamp);
@@ -197,6 +198,19 @@ std::shared_ptr<Box_mdcv> ImageDescription::create_mdcv_box() const
}
+std::shared_ptr<Box_amve> ImageDescription::create_amve_box() const
+{
+ if (!has_amve()) {
+ return {};
+ }
+
+ auto amve = std::make_shared<Box_amve>();
+ amve->amve = get_amve();
+
+ return amve;
+}
+
+
std::shared_ptr<Box_ndwt> ImageDescription::create_ndwt_box() const
{
if (!has_nominal_diffuse_white()) {
@@ -292,6 +306,13 @@ std::vector<std::shared_ptr<Box>> ImageDescription::generate_property_boxes(bool
}
+ // --- write AMVE property
+
+ if (has_amve()) {
+ properties.push_back(create_amve_box());
+ }
+
+
// --- write NDWT property
if (has_nominal_diffuse_white()) {
diff --git a/libheif/image/image_description.h b/libheif/image/image_description.h
index 41626d71..8b89502c 100644
--- a/libheif/image/image_description.h
+++ b/libheif/image/image_description.h
@@ -239,6 +239,19 @@ public:
void unset_mdcv() { m_mdcv.reset(); }
+ // --- amve (ambient viewing environment)
+
+ bool has_amve() const { return m_amve.has_value(); }
+
+ heif_ambient_viewing_environment get_amve() const { return *m_amve; }
+
+ virtual void set_amve(const heif_ambient_viewing_environment& amve)
+ {
+ m_amve = amve;
+ }
+
+ void unset_amve() { m_amve.reset(); }
+
// --- ndwt (nominal diffuse white)
// Note: a luminance of 0 is a valid value (it selects the ISO/TS 22028-5
@@ -454,6 +467,7 @@ private:
uint32_t m_PixelAspectRatio_v = 1;
heif_content_light_level m_clli{};
std::optional<heif_mastering_display_colour_volume> m_mdcv;
+ std::optional<heif_ambient_viewing_environment> m_amve;
std::optional<uint32_t> m_nominal_diffuse_white_luminance;
heif_tai_timestamp_packet* m_tai_timestamp = nullptr;
@@ -489,6 +503,8 @@ protected:
std::shared_ptr<Box_mdcv> create_mdcv_box() const;
+ std::shared_ptr<Box_amve> create_amve_box() const;
+
std::shared_ptr<Box_ndwt> create_ndwt_box() const;
std::shared_ptr<Box_pasp> create_pasp_box() const;