/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 | 1.40k | 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 | 325 | bool has_images() const { return m_meta_box != nullptr; } |
77 | | |
78 | 220 | 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 | 1.03k | 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 | | Error get_uncompressed_item_data(heif_item_id ID, std::vector<uint8_t>* data) 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 | 133 | Error append_data_from_iloc(heif_item_id ID, std::vector<uint8_t>& out_data) const { |
121 | 133 | return append_data_from_iloc(ID, out_data, 0, std::numeric_limits<uint64_t>::max()); |
122 | 133 | } |
123 | | |
124 | | Error get_item_data(heif_item_id ID, std::vector<uint8_t> *out_data, heif_metadata_compression* out_compression) const; |
125 | | |
126 | 0 | std::shared_ptr<Box_ftyp> get_ftyp_box() { return m_ftyp_box; } |
127 | | |
128 | 0 | void init_meta_box() { m_meta_box = std::make_shared<Box_meta>(); } |
129 | | |
130 | | std::shared_ptr<const Box_infe> get_infe_box(heif_item_id imageID) const; |
131 | | |
132 | | std::shared_ptr<Box_infe> get_infe_box(heif_item_id imageID); |
133 | | |
134 | | void set_iref_box(std::shared_ptr<Box_iref>); |
135 | | |
136 | 674 | std::shared_ptr<Box_iref> get_iref_box() { return m_iref_box; } |
137 | | |
138 | 0 | std::shared_ptr<const Box_iref> get_iref_box() const { return m_iref_box; } |
139 | | |
140 | 2.71k | std::shared_ptr<Box_ipco> get_ipco_box() { return m_ipco_box; } |
141 | | |
142 | | void set_ipco_box(std::shared_ptr<Box_ipco>); |
143 | | |
144 | 0 | std::shared_ptr<Box_ipco> get_ipco_box() const { return m_ipco_box; } |
145 | | |
146 | | void set_ipma_box(std::shared_ptr<Box_ipma>); |
147 | | |
148 | 2.71k | std::shared_ptr<Box_ipma> get_ipma_box() { return m_ipma_box; } |
149 | | |
150 | 0 | std::shared_ptr<Box_ipma> get_ipma_box() const { return m_ipma_box; } |
151 | | |
152 | 0 | std::shared_ptr<Box_grpl> get_grpl_box() const { return m_grpl_box; } |
153 | | |
154 | 0 | std::shared_ptr<Box_meta> get_meta_box() const { return m_meta_box; } |
155 | | |
156 | | std::shared_ptr<Box_EntityToGroup> get_entity_group(heif_entity_group_id id); |
157 | | |
158 | | Error get_properties(heif_item_id imageID, |
159 | | std::vector<std::shared_ptr<Box>>& properties) const; |
160 | | |
161 | | template<class BoxType> |
162 | | std::shared_ptr<BoxType> get_property_for_item(heif_item_id imageID) const |
163 | 0 | { |
164 | 0 | std::vector<std::shared_ptr<Box>> properties; |
165 | 0 | Error err = get_properties(imageID, properties); |
166 | 0 | if (err) { |
167 | 0 | return nullptr; |
168 | 0 | } |
169 | | |
170 | 0 | for (auto& property : properties) { |
171 | 0 | if (auto box = std::dynamic_pointer_cast<BoxType>(property)) { |
172 | 0 | return box; |
173 | 0 | } |
174 | 0 | } |
175 | | |
176 | 0 | return nullptr; |
177 | 0 | } 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 Unexecuted instantiation: std::__1::shared_ptr<Box_pixi> HeifFile::get_property_for_item<Box_pixi>(unsigned int) const |
178 | | |
179 | | std::string debug_dump_boxes() const; |
180 | | |
181 | | |
182 | | // --- writing --- |
183 | | |
184 | | heif_item_id get_unused_item_id() const; |
185 | | |
186 | | heif_item_id add_new_image(uint32_t item_type); |
187 | | |
188 | | std::shared_ptr<Box_infe> add_new_infe_box(uint32_t item_type); |
189 | | |
190 | | void add_ispe_property(heif_item_id id, uint32_t width, uint32_t height, bool essential); |
191 | | |
192 | | // set irot/imir according to heif_orientation |
193 | | void add_orientation_properties(heif_item_id id, heif_orientation); |
194 | | |
195 | | // TODO: can we remove the 'essential' parameter and take this from the box? Or is that depending on the context? |
196 | | heif_property_id add_property(heif_item_id id, const std::shared_ptr<Box>& property, bool essential); |
197 | | |
198 | | heif_property_id add_property_without_deduplication(heif_item_id id, const std::shared_ptr<Box>& property, bool essential); |
199 | | |
200 | | Result<heif_item_id> add_infe(uint32_t item_type, const uint8_t* data, size_t size); |
201 | | |
202 | | void add_infe_box(heif_item_id, std::shared_ptr<Box_infe> infe); |
203 | | |
204 | | Result<heif_item_id> add_infe_mime(const char* content_type, heif_metadata_compression content_encoding, const uint8_t* data, size_t size); |
205 | | |
206 | | Result<heif_item_id> add_precompressed_infe_mime(const char* content_type, std::string content_encoding, const uint8_t* data, size_t size); |
207 | | |
208 | | Result<heif_item_id> add_infe_uri(const char* item_uri_type, const uint8_t* data, size_t size); |
209 | | |
210 | | Error set_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, heif_metadata_compression compression); |
211 | | |
212 | | Error set_precompressed_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, std::string content_encoding); |
213 | | |
214 | | void append_iloc_data(heif_item_id id, const std::vector<uint8_t>& nal_packets, uint8_t construction_method); |
215 | | |
216 | | void replace_iloc_data(heif_item_id id, uint64_t offset, const std::vector<uint8_t>& data, uint8_t construction_method = 0); |
217 | | |
218 | | void set_iloc_box(std::shared_ptr<Box_iloc>); |
219 | | |
220 | 0 | std::shared_ptr<Box_iloc> get_iloc_box() { return m_iloc_box; } |
221 | | |
222 | | void set_primary_item_id(heif_item_id id); |
223 | | |
224 | | void add_iref_reference(heif_item_id from, uint32_t type, |
225 | | const std::vector<heif_item_id>& to); |
226 | | |
227 | | void set_iref_reference(heif_item_id from, uint32_t type, int reference_idx, heif_item_id to_item); |
228 | | |
229 | | void add_entity_group_box(const std::shared_ptr<Box>& entity_group_box); |
230 | | |
231 | | void set_auxC_property(heif_item_id id, const std::string& type); |
232 | | |
233 | | #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) |
234 | | static std::wstring convert_utf8_path_to_utf16(std::string pathutf8); |
235 | | #endif |
236 | | |
237 | | |
238 | | // --- sequences |
239 | | |
240 | 0 | std::shared_ptr<Box_moov> get_moov_box() { return m_moov_box; } |
241 | | |
242 | 0 | std::shared_ptr<Box_mvhd> get_mvhd_box() { return m_mvhd_box; } |
243 | | |
244 | | private: |
245 | | #if ENABLE_PARALLEL_TILE_DECODING |
246 | | mutable std::mutex m_read_mutex; |
247 | | #endif |
248 | | |
249 | | std::shared_ptr<FileLayout> m_file_layout; |
250 | | |
251 | | std::shared_ptr<StreamReader> m_input_stream; |
252 | | |
253 | | std::vector<std::shared_ptr<Box> > m_top_level_boxes; |
254 | | |
255 | | std::shared_ptr<Box_ftyp> m_ftyp_box; |
256 | | std::shared_ptr<Box_hdlr> m_hdlr_box; |
257 | | std::shared_ptr<Box_meta> m_meta_box; |
258 | | #if ENABLE_EXPERIMENTAL_MINI_FORMAT |
259 | | std::shared_ptr<Box_mini> m_mini_box; // meta alternative |
260 | | #endif |
261 | | |
262 | | std::shared_ptr<Box_ipco> m_ipco_box; |
263 | | std::shared_ptr<Box_ipma> m_ipma_box; |
264 | | std::shared_ptr<Box_iloc> m_iloc_box; |
265 | | std::shared_ptr<Box_idat> m_idat_box; |
266 | | std::shared_ptr<Box_iref> m_iref_box; |
267 | | std::shared_ptr<Box_pitm> m_pitm_box; |
268 | | std::shared_ptr<Box_iinf> m_iinf_box; |
269 | | std::shared_ptr<Box_grpl> m_grpl_box; |
270 | | |
271 | | std::shared_ptr<Box_iprp> m_iprp_box; |
272 | | |
273 | | std::map<heif_item_id, std::shared_ptr<Box_infe> > m_infe_boxes; |
274 | | |
275 | | std::unique_ptr<MdatData> m_mdat_data; |
276 | | |
277 | | // returns the position of the first data byte in the file |
278 | | Result<size_t> write_mdat(StreamWriter& writer); |
279 | | |
280 | | // --- sequences |
281 | | |
282 | | std::shared_ptr<Box_moov> m_moov_box; |
283 | | std::shared_ptr<Box_mvhd> m_mvhd_box; |
284 | | |
285 | | const heif_security_limits* m_limits = nullptr; |
286 | | |
287 | | Error parse_heif_file(); |
288 | | |
289 | | Error parse_heif_images(); |
290 | | |
291 | | Error parse_heif_sequences(); |
292 | | |
293 | | Error check_for_ref_cycle(heif_item_id ID, |
294 | | const std::shared_ptr<Box_iref>& iref_box) const; |
295 | | |
296 | | Error check_for_ref_cycle_recursion(heif_item_id ID, |
297 | | const std::shared_ptr<Box_iref>& iref_box, |
298 | | std::unordered_set<heif_item_id>& parent_items) const; |
299 | | }; |
300 | | |
301 | | #endif |