1919#include " Metadata/FreeImageTag.h"
2020#include " FreeImage/SimpleTools.h"
2121
22+ #include < iostream>
2223#include < array>
2324#include < cstring>
2425#include " yato/types.h"
@@ -116,6 +117,8 @@ class LibHeif
116117 decltype (&::heif_get_version_number_major) heif_get_version_number_major_f{ nullptr };
117118 decltype (&::heif_get_version_number_minor) heif_get_version_number_minor_f{ nullptr };
118119 decltype (&::heif_get_version_number_maintenance) heif_get_version_number_maintenance_f{ nullptr };
120+ decltype (&::heif_get_decoder_descriptors) heif_get_decoder_descriptors_f{ nullptr };
121+ decltype (&::heif_get_encoder_descriptors) heif_get_encoder_descriptors_f{ nullptr };
119122 decltype (&::heif_read_main_brand) heif_read_main_brand_f{ nullptr };
120123 decltype (&::heif_context_alloc) heif_context_alloc_f{ nullptr };
121124 decltype (&::heif_context_free) heif_context_free_f{ nullptr };
@@ -135,6 +138,8 @@ class LibHeif
135138 decltype (&::heif_image_handle_get_metadata_size) heif_image_handle_get_metadata_size_f{ nullptr };
136139 decltype (&::heif_image_handle_get_metadata) heif_image_handle_get_metadata_f{ nullptr };
137140 decltype (&::heif_decode_image) heif_decode_image_f{ nullptr };
141+ decltype (&::heif_decoder_descriptor_get_id_name) heif_decoder_descriptor_get_id_name_f{ nullptr };
142+ decltype (&::heif_decoder_descriptor_get_name) heif_decoder_descriptor_get_name_f{ nullptr };
138143 decltype (&::heif_image_create) heif_image_create_f{ nullptr };
139144 decltype (&::heif_image_release) heif_image_release_f{ nullptr };
140145 decltype (&::heif_image_add_plane) heif_image_add_plane_f{ nullptr };
@@ -143,6 +148,8 @@ class LibHeif
143148 decltype (&::heif_image_get_plane) heif_image_get_plane_f{ nullptr };
144149 decltype (&::heif_encoder_release) heif_encoder_release_f{ nullptr };
145150 decltype (&::heif_encoder_set_lossy_quality) heif_encoder_set_lossy_quality_f{ nullptr };
151+ decltype (&::heif_encoder_descriptor_get_id_name) heif_encoder_descriptor_get_id_name_f{ nullptr };
152+ decltype (&::heif_encoder_descriptor_get_name) heif_encoder_descriptor_get_name_f{ nullptr };
146153 decltype (&::heif_image_handle_get_number_of_thumbnails) heif_image_handle_get_number_of_thumbnails_f{ nullptr };
147154 decltype (&::heif_image_handle_get_list_of_thumbnail_IDs) heif_image_handle_get_list_of_thumbnail_IDs_f{ nullptr };
148155 decltype (&::heif_image_handle_get_thumbnail) heif_image_handle_get_thumbnail_f{ nullptr };
@@ -165,6 +172,8 @@ class LibHeif
165172 heif_get_version_number_major_f = LoadSymbol<decltype (&::heif_get_version_number_major)>(" heif_get_version_number_major" );
166173 heif_get_version_number_minor_f = LoadSymbol<decltype (&::heif_get_version_number_minor)>(" heif_get_version_number_minor" );
167174 heif_get_version_number_maintenance_f = LoadSymbol<decltype (&::heif_get_version_number_maintenance)>(" heif_get_version_number_maintenance" );
175+ heif_get_decoder_descriptors_f = LoadSymbol<decltype (&::heif_get_decoder_descriptors)>(" heif_get_decoder_descriptors" , /* required=*/ false );
176+ heif_get_encoder_descriptors_f = LoadSymbol<decltype (&::heif_get_encoder_descriptors)>(" heif_get_encoder_descriptors" , /* required=*/ false );
168177 heif_read_main_brand_f = LoadSymbol<decltype (&::heif_read_main_brand)>(" heif_read_main_brand" , /* required=*/ false );
169178 heif_context_alloc_f = LoadSymbol<decltype (&::heif_context_alloc)>(" heif_context_alloc" );
170179 heif_context_free_f = LoadSymbol<decltype (&::heif_context_free)>(" heif_context_free" );
@@ -182,6 +191,8 @@ class LibHeif
182191 heif_image_handle_get_metadata_f = LoadSymbol<decltype (&::heif_image_handle_get_metadata)>(" heif_image_handle_get_metadata" );
183192 heif_image_handle_get_preferred_decoding_colorspace_f = LoadSymbol<decltype (&::heif_image_handle_get_preferred_decoding_colorspace)>(" heif_image_handle_get_preferred_decoding_colorspace" , /* required=*/ false );
184193 heif_decode_image_f = LoadSymbol<decltype (&::heif_decode_image)>(" heif_decode_image" );
194+ heif_decoder_descriptor_get_id_name_f = LoadSymbol<decltype (&::heif_decoder_descriptor_get_id_name)>(" heif_decoder_descriptor_get_id_name" , /* required=*/ false );
195+ heif_decoder_descriptor_get_name_f = LoadSymbol<decltype (&::heif_decoder_descriptor_get_name)>(" heif_decoder_descriptor_get_name" , /* required=*/ false );
185196 heif_image_create_f = LoadSymbol<decltype (&::heif_image_create)>(" heif_image_create" );
186197 heif_image_release_f = LoadSymbol<decltype (&::heif_image_release)>(" heif_image_release" );
187198 heif_image_add_plane_f = LoadSymbol<decltype (&::heif_image_add_plane)>(" heif_image_add_plane" );
@@ -191,6 +202,8 @@ class LibHeif
191202 heif_image_get_plane_f = LoadSymbol<decltype (&::heif_image_get_plane)>(" heif_image_get_plane" );
192203 heif_encoder_release_f = LoadSymbol<decltype (&::heif_encoder_release)>(" heif_encoder_release" );
193204 heif_encoder_set_lossy_quality_f = LoadSymbol<decltype (&::heif_encoder_set_lossy_quality)>(" heif_encoder_set_lossy_quality" );
205+ heif_encoder_descriptor_get_id_name_f = LoadSymbol<decltype (&::heif_encoder_descriptor_get_id_name)>(" heif_encoder_descriptor_get_id_name" , /* required=*/ false );
206+ heif_encoder_descriptor_get_name_f = LoadSymbol<decltype (&::heif_encoder_descriptor_get_name)>(" heif_encoder_descriptor_get_name" , /* required=*/ false );
194207 heif_context_encode_image_f = LoadSymbol<decltype (&::heif_context_encode_image)>(" heif_context_encode_image" );
195208 heif_image_handle_get_number_of_thumbnails_f = LoadSymbol<decltype (&::heif_image_handle_get_number_of_thumbnails)>(" heif_image_handle_get_number_of_thumbnails" , /* required=*/ false );
196209 heif_image_handle_get_list_of_thumbnail_IDs_f = LoadSymbol<decltype (&::heif_image_handle_get_list_of_thumbnail_IDs)>(" heif_image_handle_get_list_of_thumbnail_IDs" , /* required=*/ false );
@@ -633,17 +646,86 @@ catch (...) {
633646}
634647
635648
649+ namespace
650+ {
651+ constexpr size_t kMaxCodecs = 32 ;
652+
653+ void GetDecoderDependencies (LibHeif& libHeif, heif_compression_format fmt, std::vector<FIDEPENDENCY>& depInfos)
654+ {
655+ if (!libHeif.heif_get_decoder_descriptors_f || !libHeif.heif_decoder_descriptor_get_id_name_f || !libHeif.heif_decoder_descriptor_get_name_f ) {
656+ return ;
657+ }
658+
659+ std::array<const heif_decoder_descriptor*, kMaxCodecs > decoders = { nullptr };
660+ const int count = libHeif.heif_get_decoder_descriptors_f (fmt, decoders.data (), yato::narrow_cast<int >(decoders.size ()));
661+
662+ for (int i = 0 ; i < count; ++i) {
663+ auto & dep = depInfos.emplace_back ();
664+ dep.name = libHeif.heif_decoder_descriptor_get_id_name_f (decoders[i]);
665+ dep.fullVersion = libHeif.heif_decoder_descriptor_get_name_f (decoders[i]);
666+ dep.type = FIDEP_DYNAMIC;
667+ }
668+ }
669+
670+ void GetEncoderDependencies (LibHeif& libHeif, heif_compression_format fmt, std::vector<FIDEPENDENCY>& depInfos)
671+ {
672+ if (!libHeif.heif_get_encoder_descriptors_f || !libHeif.heif_encoder_descriptor_get_id_name_f || !libHeif.heif_encoder_descriptor_get_name_f ) {
673+ return ;
674+ }
675+
676+ std::array<const heif_encoder_descriptor*, kMaxCodecs > encoders = { nullptr };
677+ const int count = libHeif.heif_get_encoder_descriptors_f (fmt, nullptr , encoders.data (), yato::narrow_cast<int >(encoders.size ()));
678+
679+ for (int i = 0 ; i < count; ++i) {
680+ auto & dep = depInfos.emplace_back ();
681+ dep.name = libHeif.heif_encoder_descriptor_get_id_name_f (encoders[i]);
682+ dep.fullVersion = libHeif.heif_encoder_descriptor_get_name_f (encoders[i]);
683+ dep.type = FIDEP_DYNAMIC;
684+ }
685+ }
636686
637- std::unique_ptr<FIDEPENDENCY> MakeHeifDependencyInfo ()
687+ std::vector<FIDEPENDENCY> GetHeifDependencies (LibHeif& libHeif) {
688+ std::vector<FIDEPENDENCY> depInfos{};
689+ GetDecoderDependencies (libHeif, heif_compression_HEVC, depInfos);
690+ GetDecoderDependencies (libHeif, heif_compression_AV1, depInfos);
691+ GetEncoderDependencies (libHeif, heif_compression_HEVC, depInfos);
692+ GetEncoderDependencies (libHeif, heif_compression_AV1, depInfos);
693+
694+ depInfos.shrink_to_fit ();
695+ for (size_t i = 0 ; i < depInfos.size () - 1 ; ++i) {
696+ depInfos[i].next = &depInfos[i + 1 ];
697+ }
698+
699+ return depInfos;
700+ }
701+
702+ const char * GetHeifFullVersion (LibHeif& libHeif)
703+ {
704+ static char buffer[256 ] = { 0 };
705+ std::snprintf (buffer, std::size (buffer), " LibHeif v%s" , libHeif.heif_get_version_f ());
706+ return buffer;
707+ }
708+
709+ } // namespace
710+
711+
712+
713+ const FIDEPENDENCY* GetHeifDependencyInfo ()
638714try {
639715 auto & libHeif = LibHeif::GetInstance ();
640- auto info = std::make_unique<FIDEPENDENCY>();
641- info->type = FIDEP_DYNAMIC;
642- info->name = " LibHeif" ;
643- info->fullVersion = libHeif.heif_get_version_f ();
644- info->majorVersion = libHeif.heif_get_version_number_major_f ();
645- info->minorVersion = libHeif.heif_get_version_number_minor_f ();
646- return info;
716+
717+ static const std::vector<FIDEPENDENCY> codecDeps = GetHeifDependencies (libHeif);
718+
719+ static const FIDEPENDENCY info = {
720+ .name = " LibHeif" ,
721+ .fullVersion = GetHeifFullVersion (libHeif),
722+ .majorVersion = yato::narrow_cast<uint32_t >(libHeif.heif_get_version_number_major_f ()),
723+ .minorVersion = yato::narrow_cast<uint32_t >(libHeif.heif_get_version_number_minor_f ()),
724+ .type = FIDEP_DYNAMIC,
725+ .next = !codecDeps.empty () ? &codecDeps[0 ] : nullptr
726+ };
727+
728+ return &info;
647729}
648730catch (...) {
649731 return nullptr ;
0 commit comments