From fb06b56caf2d9cb53d434486798bd047f3b57746 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 19 Aug 2024 00:57:51 +0200 Subject: [PATCH] read bitstream config for HEVC and AV1 in ImageItem* classes --- libheif/codecs/avif.cc | 45 ++++++++++++++++++++++++++++++++++++ libheif/codecs/avif.h | 3 +++ libheif/codecs/hevc.cc | 41 ++++++++++++++++++++++++++++++++ libheif/codecs/hevc.h | 4 ++++ libheif/codecs/image_item.cc | 4 ++-- libheif/codecs/image_item.h | 4 ++-- libheif/codecs/tild.cc | 7 +++++- libheif/file.cc | 3 +++ 8 files changed, 106 insertions(+), 5 deletions(-) diff --git a/libheif/codecs/avif.cc b/libheif/codecs/avif.cc index 933944b2ad..3ad260aa0e 100644 --- a/libheif/codecs/avif.cc +++ b/libheif/codecs/avif.cc @@ -23,6 +23,7 @@ #include "bitstream.h" #include "common_utils.h" #include "libheif/api_structs.h" +#include "file.h" #include #include #include @@ -605,3 +606,47 @@ Result ImageItem_AVIF::encode(const std::shared_ptr> ImageItem_AVIF::read_bitstream_configuration_data(heif_item_id itemId) const +{ + std::vector data; + + // --- get properties for this image + + std::vector> properties; + auto ipma_box = get_file()->get_ipma_box(); + Error err = get_file()->get_ipco_box()->get_properties_for_item_ID(itemId, ipma_box, properties); + if (err) + { + return err; + } + + // --- get codec configuration + + std::shared_ptr av1C_box; + for (auto &prop : properties) + { + if (prop->get_short_type() == fourcc("av1C")) + { + av1C_box = std::dynamic_pointer_cast(prop); + if (av1C_box) + { + break; + } + } + } + + if (!av1C_box) + { + return Error(heif_error_Invalid_input, + heif_suberror_No_av1C_box); + } + else if (!av1C_box->get_headers(&data)) + { + return Error(heif_error_Invalid_input, + heif_suberror_No_item_data); + } + + return data; +} diff --git a/libheif/codecs/avif.h b/libheif/codecs/avif.h index 13ac464d52..830926ce54 100644 --- a/libheif/codecs/avif.h +++ b/libheif/codecs/avif.h @@ -172,6 +172,9 @@ class ImageItem_AVIF : public ImageItem struct heif_encoder* encoder, const struct heif_encoding_options& options, enum heif_image_input_class input_class) override; + +protected: + Result> read_bitstream_configuration_data(heif_item_id itemId) const override; }; #endif diff --git a/libheif/codecs/hevc.cc b/libheif/codecs/hevc.cc index 3f2b755e10..06ccd6b28e 100644 --- a/libheif/codecs/hevc.cc +++ b/libheif/codecs/hevc.cc @@ -21,6 +21,7 @@ #include "hevc.h" #include "bitstream.h" #include "error.h" +#include "file.h" #include #include @@ -721,3 +722,43 @@ Result ImageItem_HEVC::encode(const std::shared_ptr> ImageItem_HEVC::read_bitstream_configuration_data(heif_item_id itemId) const +{ + std::vector data; + + // --- get properties for this image + std::vector> properties; + auto ipma_box = get_file()->get_ipma_box(); + Error err = get_file()->get_ipco_box()->get_properties_for_item_ID(itemId, ipma_box, properties); + if (err) + { + return err; + } + + // --- get codec configuration + + std::shared_ptr hvcC_box; + for (auto &prop : properties) + { + if (prop->get_short_type() == fourcc("hvcC")) + { + hvcC_box = std::dynamic_pointer_cast(prop); + if (hvcC_box) + { + break; + } + } + } + + if (!hvcC_box) { + return Error{heif_error_Invalid_input, + heif_suberror_No_hvcC_box}; + } + else if (!hvcC_box->get_headers(&data)) { + return Error{heif_error_Invalid_input, + heif_suberror_No_item_data}; + } + + return data; +} diff --git a/libheif/codecs/hevc.h b/libheif/codecs/hevc.h index 3edab28c04..2702caca52 100644 --- a/libheif/codecs/hevc.h +++ b/libheif/codecs/hevc.h @@ -137,6 +137,10 @@ class ImageItem_HEVC : public ImageItem heif_compression_format get_compression_format() const override { return heif_compression_HEVC; } +protected: + Result> read_bitstream_configuration_data(heif_item_id itemId) const override; + +public: Result encode(const std::shared_ptr& image, struct heif_encoder* encoder, diff --git a/libheif/codecs/image_item.cc b/libheif/codecs/image_item.cc index 86361cc6cd..b508ed3a51 100644 --- a/libheif/codecs/image_item.cc +++ b/libheif/codecs/image_item.cc @@ -1026,12 +1026,12 @@ Result> ImageItem::decode_image(heif_colorspace } -std::vector ImageItem::read_bitstream_configuration_data_override(heif_item_id itemId, heif_compression_format format) const +Result> ImageItem::read_bitstream_configuration_data_override(heif_item_id itemId, heif_compression_format format) const { auto item_codec = ImageItem::alloc_for_compression_format(const_cast(get_context()), format); assert(item_codec); - return read_bitstream_configuration_data(itemId); + return item_codec->read_bitstream_configuration_data(itemId); } diff --git a/libheif/codecs/image_item.h b/libheif/codecs/image_item.h index cb183fe9ce..35447b7323 100644 --- a/libheif/codecs/image_item.h +++ b/libheif/codecs/image_item.h @@ -384,9 +384,9 @@ class ImageItem : public ErrorBuffer const struct heif_decoding_options& options, const std::vector& data); - std::vector read_bitstream_configuration_data_override(heif_item_id itemId, heif_compression_format format) const; + Result> read_bitstream_configuration_data_override(heif_item_id itemId, heif_compression_format format) const; - virtual std::vector read_bitstream_configuration_data(heif_item_id itemId) const { return {}; } + virtual Result> read_bitstream_configuration_data(heif_item_id itemId) const { return std::vector{}; } virtual Result encode(const std::shared_ptr& image, struct heif_encoder* encoder, diff --git a/libheif/codecs/tild.cc b/libheif/codecs/tild.cc index 68b5a54464..32b5b25f1f 100644 --- a/libheif/codecs/tild.cc +++ b/libheif/codecs/tild.cc @@ -468,7 +468,12 @@ Result> ImageItem_Tild::decode_grid_tile(const h // --- get compressed data - std::vector data = read_bitstream_configuration_data_override(get_id(), format); + Result> dataResult = read_bitstream_configuration_data_override(get_id(), format); + if (dataResult.error) { + return dataResult.error; + } + + std::vector& data = dataResult.value; // --- decode diff --git a/libheif/file.cc b/libheif/file.cc index 578fb6e2fa..8cb8a9a4d9 100644 --- a/libheif/file.cc +++ b/libheif/file.cc @@ -1023,6 +1023,8 @@ const Error HeifFile::do_decompress_data(std::shared_ptr &cmpC_box, st } #endif + +// TODO: replace with function in ImageItem const Error HeifFile::get_compressed_image_data_hvc1(heif_item_id ID, std::vector *data, const Box_iloc::Item *item) const { // --- get properties for this image @@ -1108,6 +1110,7 @@ const Error HeifFile::get_compressed_image_data_vvc(heif_item_id ID, std::vector return m_iloc_box->read_data(*item, m_input_stream, m_idat_box, data); } +// TODO: replace with function in ImageItem const Error HeifFile::get_compressed_image_data_av1(heif_item_id ID, std::vector *data, const Box_iloc::Item *item) const { // --- --- --- AV1