libheif/file.h (199 lines of code) (raw):

/* * HEIF codec. * Copyright (c) 2017 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_FILE_H #define LIBHEIF_FILE_H #include "box.h" #include "nclx.h" #include "codecs/avif.h" #include "codecs/hevc.h" #include "codecs/vvc.h" #include "codecs/uncompressed_box.h" #include <map> #include <memory> #include <string> #include <map> #include <vector> #include <unordered_set> #if ENABLE_PARALLEL_TILE_DECODING #include <mutex> #endif class HeifPixelImage; class HeifImage; class Box_j2kH; class HeifFile { public: HeifFile(); ~HeifFile(); Error read(const std::shared_ptr<StreamReader>& reader); Error read_from_file(const char* input_filename); Error read_from_memory(const void* data, size_t size, bool copy); void new_empty_file(); void set_brand(heif_compression_format format, bool miaf_compatible, bool moov_flag); void write(StreamWriter& writer); void patch_stco_data(StreamWriter& writer); Error get_compressed_image_data_for_moov(heif_item_id ID, std::vector<uint8_t>* out_data) const; Error get_image_data_for_moov(heif_item_id ID, const std::shared_ptr<StreamReader>& istr, std::vector<uint8_t>* dest) const; int get_num_images() const { return static_cast<int>(m_infe_boxes.size()); } heif_item_id get_primary_image_ID() const { return m_pitm_box->get_item_ID(); } size_t get_number_of_items() const { return m_infe_boxes.size(); } std::vector<heif_item_id> get_item_IDs() const; bool image_exists(heif_item_id ID) const; bool has_item_with_id(heif_item_id ID) const; std::string get_item_type(heif_item_id ID) const; std::string get_content_type(heif_item_id ID) const; std::string get_item_uri_type(heif_item_id ID) const; Error get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>* out_data) const; Error get_item_data(heif_item_id ID, std::vector<uint8_t> *out_data, heif_metadata_compression* out_compression) const; std::shared_ptr<Box_ftyp> get_ftyp_box() { return m_ftyp_box; } std::shared_ptr<const Box_infe> get_infe_box(heif_item_id imageID) const; std::shared_ptr<Box_infe> get_infe_box(heif_item_id imageID); std::shared_ptr<Box_iref> get_iref_box() { return m_iref_box; } std::shared_ptr<Box_ipco> get_ipco_box() { return m_ipco_box; } std::shared_ptr<Box_ipco> get_ipco_box() const { return m_ipco_box; } std::shared_ptr<Box_ipma> get_ipma_box() { return m_ipma_box; } std::shared_ptr<Box_ipma> get_ipma_box() const { return m_ipma_box; } void set_moov_flag(bool moov_flag) {m_moov_flag = moov_flag;} bool get_moov_flag() {return m_moov_flag;} std::shared_ptr<Box_mvhd> get_mvhd_box() { return m_mvhd_box; } std::shared_ptr<Box_tkhd> get_tkhd_box() { return m_tkhd_box; } std::shared_ptr<Box_mdhd> get_mdhd_box() { return m_mdhd_box; } std::shared_ptr<Box_hvc1> get_hvc1_box() { return m_hvc1_box; } std::shared_ptr<Box_hvcC> get_hvcC_box() { return m_hvcC_box; } std::shared_ptr<Box_stts> get_stts_box() { return m_stts_box; } std::shared_ptr<Box_stss> get_stss_box() { return m_stss_box; } std::shared_ptr<Box_stsc> get_stsc_box() { return m_stsc_box;} std::shared_ptr<Box_stsz> get_stsz_box() { return m_stsz_box;} void add_movie_box(); int get_luma_bits_per_pixel_from_configuration() const; Error get_properties(heif_item_id imageID, std::vector<std::shared_ptr<Box>>& properties) const; template<class BoxType> std::shared_ptr<BoxType> get_property(heif_item_id imageID) const { std::vector<std::shared_ptr<Box>> properties; Error err = get_properties(imageID, properties); if (err) { return nullptr; } for (auto& property : properties) { if (auto box = std::dynamic_pointer_cast<BoxType>(property)) { return box; } } return nullptr; } heif_chroma get_image_chroma_from_configuration(heif_item_id imageID) const; int get_luma_bits_per_pixel_from_configuration(heif_item_id imageID) const; int get_chroma_bits_per_pixel_from_configuration(heif_item_id imageID) const; std::string debug_dump_boxes() const; // --- writing --- heif_item_id get_unused_item_id() const; heif_item_id add_new_image(const char* item_type); heif_item_id add_new_hidden_image(const char* item_type); std::shared_ptr<Box_infe> add_new_infe_box(const char* item_type); void add_av1C_property(heif_item_id id, const Box_av1C::configuration& config); void add_vvcC_property(heif_item_id id); Error append_vvcC_nal_data(heif_item_id id, const std::vector<uint8_t>& data); Error append_vvcC_nal_data(heif_item_id id, const uint8_t* data, size_t size); Error set_vvcC_configuration(heif_item_id id, const Box_vvcC::configuration& config); void add_hvcC_property(heif_item_id id); Error append_hvcC_nal_data(heif_item_id id, const std::vector<uint8_t>& data); Error append_hvcC_nal_data(heif_item_id id, const uint8_t* data, size_t size); Error set_hvcC_configuration(heif_item_id id, const Box_hvcC::configuration& config); Error set_av1C_configuration(heif_item_id id, const Box_av1C::configuration& config); std::shared_ptr<Box_j2kH> add_j2kH_property(heif_item_id id); heif_item_id add_new_infe_box_returnID(const char* item_type); Error set_hvcC_configuration(const Box_hvcC::configuration& config); Error append_hvcC_nal_data(const uint8_t* data, size_t size); Error append_sample_entry_size(uint32_t size); Error add_frame_duration_in_TimeScale(uint64_t duration); Error add_frame_sample_in_chunk(); Error record_sync_data_in_stss(uint8_t nal_type); void add_ispe_property(heif_item_id id, uint32_t width, uint32_t height); void add_clap_property(heif_item_id id, uint32_t clap_width, uint32_t clap_height, uint32_t image_width, uint32_t image_height); // set irot/imir according to heif_orientation void add_orientation_properties(heif_item_id id, heif_orientation); void add_pixi_property(heif_item_id id, uint8_t c1, uint8_t c2 = 0, uint8_t c3 = 0); heif_property_id add_property(heif_item_id id, const std::shared_ptr<Box>& property, bool essential); Result<heif_item_id> add_infe(const char* item_type, const uint8_t* data, size_t size); Result<heif_item_id> add_infe_mime(const char* content_type, heif_metadata_compression content_encoding, const uint8_t* data, size_t size); Result<heif_item_id> add_precompressed_infe_mime(const char* content_type, std::string content_encoding, const uint8_t* data, size_t size); Result<heif_item_id> add_infe_uri(const char* item_uri_type, const uint8_t* data, size_t size); Error set_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, heif_metadata_compression compression); Error set_precompressed_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, std::string content_encoding); void append_iloc_data(heif_item_id id, const std::vector<uint8_t>& nal_packets, uint8_t construction_method = 0); void append_iloc_data_with_4byte_size(heif_item_id id, const uint8_t* data, size_t size); void set_primary_item_id(heif_item_id id); void add_iref_reference(heif_item_id from, uint32_t type, const std::vector<heif_item_id>& to); void set_auxC_property(heif_item_id id, const std::string& type); void set_color_profile(heif_item_id id, const std::shared_ptr<const color_profile>& profile); // TODO: the hdlr box is probably not the right place for this. Into which box should we write comments? void set_hdlr_library_info(const std::string& encoder_plugin_version); #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) static std::wstring convert_utf8_path_to_utf16(std::string pathutf8); #endif private: #if ENABLE_PARALLEL_TILE_DECODING mutable std::mutex m_read_mutex; #endif std::shared_ptr<StreamReader> m_input_stream; std::vector<std::shared_ptr<Box> > m_top_level_boxes; bool m_moov_flag = 0; std::shared_ptr<Box_moov> m_moov_box; std::shared_ptr<Box_mvhd> m_mvhd_box; std::shared_ptr<Box_trak> m_trak_box; std::shared_ptr<Box_tkhd> m_tkhd_box; std::shared_ptr<Box_mdia> m_mdia_box; std::shared_ptr<Box_mdhd> m_mdhd_box; std::shared_ptr<Box_minf> m_minf_box; std::shared_ptr<Box_vmhd> m_vmhd_box; std::shared_ptr<Box_dinf> m_dinf_box; std::shared_ptr<Box_dref> m_dref_box; std::shared_ptr<Box_url> m_url_box; std::shared_ptr<Box_stbl> m_stbl_box; std::shared_ptr<Box_stsd> m_stsd_box; std::shared_ptr<Box_hvc1> m_hvc1_box; std::shared_ptr<Box_hvcC> m_hvcC_box; std::shared_ptr<Box_ccst> m_ccst_box; std::shared_ptr<Box_stsz> m_stsz_box; std::shared_ptr<Box_stts> m_stts_box; std::shared_ptr<Box_stsc> m_stsc_box; std::shared_ptr<Box_stco> m_stco_box; std::shared_ptr<Box_stss> m_stss_box; std::shared_ptr<Box_ftyp> m_ftyp_box; std::shared_ptr<Box_hdlr> m_hdlr_box; std::shared_ptr<Box_meta> m_meta_box; std::shared_ptr<Box_ipco> m_ipco_box; std::shared_ptr<Box_ipma> m_ipma_box; std::shared_ptr<Box_iloc> m_iloc_box; std::shared_ptr<Box_idat> m_idat_box; std::shared_ptr<Box_iref> m_iref_box; std::shared_ptr<Box_pitm> m_pitm_box; std::shared_ptr<Box_iinf> m_iinf_box; std::shared_ptr<Box_iprp> m_iprp_box; std::map<heif_item_id, std::shared_ptr<Box_infe> > m_infe_boxes; // list of image items (does not include hidden images or Exif data) //std::vector<heif_item_id> m_valid_image_IDs; Error parse_heif_file(BitstreamRange& bitstream); Error check_for_ref_cycle(heif_item_id ID, const std::shared_ptr<Box_iref>& iref_box) const; Error check_for_ref_cycle_recursion(heif_item_id ID, const std::shared_ptr<Box_iref>& iref_box, std::unordered_set<heif_item_id>& parent_items) const; int jpeg_get_bits_per_pixel(heif_item_id imageID) const; const Error get_compressed_image_data_hvc1(heif_item_id ID, std::vector<uint8_t> *data, const Box_iloc::Item *item) const; const Error get_compressed_image_data_vvc(heif_item_id ID, std::vector<uint8_t> *data, const Box_iloc::Item *item) const; #if WITH_UNCOMPRESSED_CODEC const Error get_compressed_image_data_uncompressed(heif_item_id ID, std::vector<uint8_t> *data, const Box_iloc::Item *item) const; const Error do_decompress_data(std::shared_ptr<Box_cmpC> &cmpC_box, std::vector<uint8_t> compressed_data, std::vector<uint8_t> *data) const; #endif const Error get_compressed_image_data_av1(heif_item_id ID, std::vector<uint8_t> *data, const Box_iloc::Item *item) const; const Error get_compressed_image_data_jpeg2000(heif_item_id ID, const Box_iloc::Item *item, std::vector<uint8_t> *data) const; const Error get_compressed_image_data_jpeg(heif_item_id ID, std::vector<uint8_t> *data, const Box_iloc::Item *item) const; }; #endif