/src/libheif/libheif/file.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * HEIF codec. |
3 | | * Copyright (c) 2017 Dirk Farin <dirk.farin@gmail.com> |
4 | | * |
5 | | * This file is part of libheif. |
6 | | * |
7 | | * libheif is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation, either version 3 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * libheif is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libheif. If not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #ifndef LIBHEIF_FILE_H |
22 | | #define LIBHEIF_FILE_H |
23 | | |
24 | | #include "box.h" |
25 | | #include "nclx.h" |
26 | | #include "image-items/avif.h" |
27 | | #include "image-items/hevc.h" |
28 | | #include "image-items/vvc.h" |
29 | | //#include "codecs/uncompressed/unc_boxes.h" |
30 | | #include "file_layout.h" |
31 | | |
32 | | #include <map> |
33 | | #include <memory> |
34 | | #include <string> |
35 | | #include <map> |
36 | | #include <vector> |
37 | | #include <unordered_set> |
38 | | #include <limits> |
39 | | #include <utility> |
40 | | #include "mdat_data.h" |
41 | | |
42 | | #if ENABLE_PARALLEL_TILE_DECODING |
43 | | |
44 | | #include <mutex> |
45 | | |
46 | | #endif |
47 | | |
48 | | |
49 | | class HeifPixelImage; |
50 | | |
51 | | class Box_j2kH; |
52 | | |
53 | | class Box_moov; |
54 | | |
55 | | class Box_mvhd; |
56 | | |
57 | | |
58 | | |
59 | | class HeifFile |
60 | | { |
61 | | public: |
62 | | HeifFile(); |
63 | | |
64 | | ~HeifFile(); |
65 | | |
66 | | // The limits will be shared from the HeifContext limits. |
67 | | // You have to make sure that the pointer points to a valid object as long as the HeifFile is used. |
68 | 38.1k | void set_security_limits(const heif_security_limits* limits) { m_limits = limits; } |
69 | | |
70 | | Error read(const std::shared_ptr<StreamReader>& reader); |
71 | | |
72 | | Error read_from_file(const char* input_filename); |
73 | | |
74 | | Error read_from_memory(const void* data, size_t size, bool copy); |
75 | | |
76 | 15.3k | bool has_images() const { return m_meta_box != nullptr; } |
77 | | |
78 | 15.0k | bool has_sequences() const { return m_moov_box != nullptr; } |
79 | | |
80 | 0 | std::shared_ptr<StreamReader> get_reader() { return m_input_stream; } |
81 | | |
82 | | void new_empty_file(); |
83 | | |
84 | | void init_for_image(); |
85 | | |
86 | | void init_for_sequence(); |
87 | | |
88 | 0 | void set_hdlr_box(std::shared_ptr<Box_hdlr> box) { m_hdlr_box = std::move(box); } |
89 | | |
90 | | size_t append_mdat_data(const std::vector<uint8_t>& data); |
91 | | |
92 | | void derive_box_versions(); |
93 | | |
94 | | void write(StreamWriter& writer); |
95 | | |
96 | 0 | int get_num_images() const { return static_cast<int>(m_infe_boxes.size()); } |
97 | | |
98 | 17.9k | heif_item_id get_primary_image_ID() const { return m_pitm_box->get_item_ID(); } |
99 | | |
100 | 0 | size_t get_number_of_items() const { return m_infe_boxes.size(); } |
101 | | |
102 | | std::vector<heif_item_id> get_item_IDs() const; |
103 | | |
104 | | bool item_exists(heif_item_id ID) const; |
105 | | |
106 | | bool has_item_with_id(heif_item_id ID) const; |
107 | | |
108 | | uint32_t get_item_type_4cc(heif_item_id ID) const; |
109 | | |
110 | | std::string get_content_type(heif_item_id ID) const; |
111 | | |
112 | | std::string get_item_uri_type(heif_item_id ID) const; |
113 | | |
114 | | Result<std::vector<uint8_t>> get_uncompressed_item_data(heif_item_id ID) const; |
115 | | |
116 | | Error append_data_from_file_range(std::vector<uint8_t>& out_data, uint64_t offset, uint32_t size) const; |
117 | | |
118 | | Error append_data_from_iloc(heif_item_id ID, std::vector<uint8_t>& out_data, uint64_t offset, uint64_t size) const; |
119 | | |
120 | 15.0k | Error append_data_from_iloc(heif_item_id ID, std::vector<uint8_t>& out_data) const { |
121 | 15.0k | return append_data_from_iloc(ID, out_data, 0, std::numeric_limits<uint64_t>::max()); |
122 | 15.0k | } |
123 | | |
124 | | // If `out_compression` is not NULL, the compression method is returned there and the compressed data is returned. |
125 | | // If `out_compression` is NULL, the data is returned decompressed. |
126 | | Result<std::vector<uint8_t>> get_item_data(heif_item_id ID, heif_metadata_compression* out_compression) const; |
127 | | |
128 | 0 | std::shared_ptr<Box_ftyp> get_ftyp_box() { return m_ftyp_box; } |
129 | | |
130 | 0 | void init_meta_box() { m_meta_box = std::make_shared<Box_meta>(); } |
131 | | |
132 | | std::shared_ptr<const Box_infe> get_infe_box(heif_item_id imageID) const; |
133 | | |
134 | | std::shared_ptr<Box_infe> get_infe_box(heif_item_id imageID); |
135 | | |
136 | | void set_iref_box(std::shared_ptr<Box_iref>); |
137 | | |
138 | 15.3k | std::shared_ptr<Box_iref> get_iref_box() { return m_iref_box; } |
139 | | |
140 | 0 | std::shared_ptr<const Box_iref> get_iref_box() const { return m_iref_box; } |
141 | | |
142 | 21.5k | std::shared_ptr<Box_ipco> get_ipco_box() { return m_ipco_box; } |
143 | | |
144 | | void set_ipco_box(std::shared_ptr<Box_ipco>); |
145 | | |
146 | 0 | std::shared_ptr<Box_ipco> get_ipco_box() const { return m_ipco_box; } |
147 | | |
148 | | void set_ipma_box(std::shared_ptr<Box_ipma>); |
149 | | |
150 | 21.5k | std::shared_ptr<Box_ipma> get_ipma_box() { return m_ipma_box; } |
151 | | |
152 | 0 | std::shared_ptr<Box_ipma> get_ipma_box() const { return m_ipma_box; } |
153 | | |
154 | 0 | std::shared_ptr<Box_grpl> get_grpl_box() const { return m_grpl_box; } |
155 | | |
156 | 0 | std::shared_ptr<Box_meta> get_meta_box() const { return m_meta_box; } |
157 | | |
158 | | std::shared_ptr<Box_EntityToGroup> get_entity_group(heif_entity_group_id id); |
159 | | |
160 | | Error get_properties(heif_item_id imageID, |
161 | | std::vector<std::shared_ptr<Box>>& properties) const; |
162 | | |
163 | | template<class BoxType> |
164 | | std::shared_ptr<BoxType> get_property_for_item(heif_item_id imageID) const |
165 | 0 | { |
166 | 0 | std::vector<std::shared_ptr<Box>> properties; |
167 | 0 | Error err = get_properties(imageID, properties); |
168 | 0 | if (err) { |
169 | 0 | return nullptr; |
170 | 0 | } |
171 | | |
172 | 0 | for (auto& property : properties) { |
173 | 0 | if (auto box = std::dynamic_pointer_cast<BoxType>(property)) { |
174 | 0 | return box; |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | 0 | return nullptr; |
179 | 0 | } Unexecuted instantiation: std::__1::shared_ptr<Box_pixi> HeifFile::get_property_for_item<Box_pixi>(unsigned int) const Unexecuted instantiation: std::__1::shared_ptr<Box_taic> HeifFile::get_property_for_item<Box_taic>(unsigned int) const Unexecuted instantiation: std::__1::shared_ptr<Box_itai> HeifFile::get_property_for_item<Box_itai>(unsigned int) const |
180 | | |
181 | | std::string debug_dump_boxes() const; |
182 | | |
183 | | |
184 | | // --- writing --- |
185 | | |
186 | | heif_item_id get_unused_item_id() const; |
187 | | |
188 | | heif_item_id add_new_image(uint32_t item_type); |
189 | | |
190 | | std::shared_ptr<Box_infe> add_new_infe_box(uint32_t item_type); |
191 | | |
192 | | void add_ispe_property(heif_item_id id, uint32_t width, uint32_t height, bool essential); |
193 | | |
194 | | // set irot/imir according to heif_orientation |
195 | | void add_orientation_properties(heif_item_id id, heif_orientation); |
196 | | |
197 | | // TODO: can we remove the 'essential' parameter and take this from the box? Or is that depending on the context? |
198 | | heif_property_id add_property(heif_item_id id, const std::shared_ptr<Box>& property, bool essential); |
199 | | |
200 | | heif_property_id add_property_without_deduplication(heif_item_id id, const std::shared_ptr<Box>& property, bool essential); |
201 | | |
202 | | Result<heif_item_id> add_infe(uint32_t item_type, const uint8_t* data, size_t size); |
203 | | |
204 | | void add_infe_box(heif_item_id, std::shared_ptr<Box_infe> infe); |
205 | | |
206 | | Result<heif_item_id> add_infe_mime(const char* content_type, heif_metadata_compression content_encoding, const uint8_t* data, size_t size); |
207 | | |
208 | | Result<heif_item_id> add_precompressed_infe_mime(const char* content_type, std::string content_encoding, const uint8_t* data, size_t size); |
209 | | |
210 | | Result<heif_item_id> add_infe_uri(const char* item_uri_type, const uint8_t* data, size_t size); |
211 | | |
212 | | Error set_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, heif_metadata_compression compression); |
213 | | |
214 | | Error set_precompressed_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, std::string content_encoding); |
215 | | |
216 | | void append_iloc_data(heif_item_id id, const std::vector<uint8_t>& nal_packets, uint8_t construction_method); |
217 | | |
218 | | void replace_iloc_data(heif_item_id id, uint64_t offset, const std::vector<uint8_t>& data, uint8_t construction_method = 0); |
219 | | |
220 | | void set_iloc_box(std::shared_ptr<Box_iloc>); |
221 | | |
222 | 0 | std::shared_ptr<Box_iloc> get_iloc_box() { return m_iloc_box; } |
223 | | |
224 | | void set_primary_item_id(heif_item_id id); |
225 | | |
226 | | void add_iref_reference(heif_item_id from, uint32_t type, |
227 | | const std::vector<heif_item_id>& to); |
228 | | |
229 | | void set_iref_reference(heif_item_id from, uint32_t type, int reference_idx, heif_item_id to_item); |
230 | | |
231 | | void add_entity_group_box(const std::shared_ptr<Box>& entity_group_box); |
232 | | |
233 | | void set_auxC_property(heif_item_id id, const std::string& type); |
234 | | |
235 | | #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) |
236 | | static std::wstring convert_utf8_path_to_utf16(std::string pathutf8); |
237 | | #endif |
238 | | |
239 | | |
240 | | // --- sequences |
241 | | |
242 | 0 | std::shared_ptr<Box_moov> get_moov_box() { return m_moov_box; } |
243 | | |
244 | 0 | std::shared_ptr<Box_mvhd> get_mvhd_box() { return m_mvhd_box; } |
245 | | |
246 | | private: |
247 | | #if ENABLE_PARALLEL_TILE_DECODING |
248 | | mutable std::mutex m_read_mutex; |
249 | | #endif |
250 | | |
251 | | std::shared_ptr<FileLayout> m_file_layout; |
252 | | |
253 | | std::shared_ptr<StreamReader> m_input_stream; |
254 | | |
255 | | std::vector<std::shared_ptr<Box> > m_top_level_boxes; |
256 | | |
257 | | std::shared_ptr<Box_ftyp> m_ftyp_box; |
258 | | std::shared_ptr<Box_hdlr> m_hdlr_box; |
259 | | std::shared_ptr<Box_meta> m_meta_box; |
260 | | #if ENABLE_EXPERIMENTAL_MINI_FORMAT |
261 | | std::shared_ptr<Box_mini> m_mini_box; // meta alternative |
262 | | #endif |
263 | | |
264 | | std::shared_ptr<Box_ipco> m_ipco_box; |
265 | | std::shared_ptr<Box_ipma> m_ipma_box; |
266 | | std::shared_ptr<Box_iloc> m_iloc_box; |
267 | | std::shared_ptr<Box_idat> m_idat_box; |
268 | | std::shared_ptr<Box_iref> m_iref_box; |
269 | | std::shared_ptr<Box_pitm> m_pitm_box; |
270 | | std::shared_ptr<Box_iinf> m_iinf_box; |
271 | | std::shared_ptr<Box_grpl> m_grpl_box; |
272 | | |
273 | | std::shared_ptr<Box_iprp> m_iprp_box; |
274 | | |
275 | | std::map<heif_item_id, std::shared_ptr<Box_infe> > m_infe_boxes; |
276 | | |
277 | | std::unique_ptr<MdatData> m_mdat_data; |
278 | | |
279 | | // returns the position of the first data byte in the file |
280 | | Result<size_t> write_mdat(StreamWriter& writer); |
281 | | |
282 | | // --- sequences |
283 | | |
284 | | std::shared_ptr<Box_moov> m_moov_box; |
285 | | std::shared_ptr<Box_mvhd> m_mvhd_box; |
286 | | |
287 | | const heif_security_limits* m_limits = nullptr; |
288 | | |
289 | | Error parse_heif_file(); |
290 | | |
291 | | Error parse_heif_images(); |
292 | | |
293 | | Error parse_heif_sequences(); |
294 | | |
295 | | Error check_for_ref_cycle(heif_item_id ID, |
296 | | const std::shared_ptr<Box_iref>& iref_box) const; |
297 | | |
298 | | Error check_for_ref_cycle_recursion(heif_item_id ID, |
299 | | const std::shared_ptr<Box_iref>& iref_box, |
300 | | std::unordered_set<heif_item_id>& parent_items) const; |
301 | | }; |
302 | | |
303 | | #endif |