Coverage Report

Created: 2026-07-20 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libheif/libheif/mini.h
Line
Count
Source
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2024 Brad Hards <bradh@frogmouth.net>
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_MINI_H
22
#define LIBHEIF_MINI_H
23
24
#include "libheif/heif.h"
25
#include "box.h"
26
27
#include <memory>
28
#include <string>
29
#include <vector>
30
#include <utility>
31
32
class Box_mini : public Box
33
{
34
public:
35
  Box_mini()
36
1.59k
  {
37
1.59k
    set_short_type(fourcc("mini"));
38
1.59k
  }
39
40
  Error create_expanded_boxes(class HeifFile* file);
41
42
  // --- Getters ---
43
44
189
  bool get_icc_flag() const { return m_icc_flag; }
45
570
  bool get_exif_flag() const { return m_exif_flag; }
46
570
  bool get_xmp_flag() const { return m_xmp_flag; }
47
48
189
  uint32_t get_width() const { return m_width; }
49
189
  uint32_t get_height() const { return m_height; }
50
51
567
  uint8_t get_bit_depth() const { return m_bit_depth; }
52
53
187
  uint8_t get_orientation() const { return m_orientation; }
54
55
362
  std::vector<uint8_t> get_main_item_codec_config() const { return m_main_item_codec_config; }
56
216
  std::vector<uint8_t> get_alpha_item_codec_config() const { return m_alpha_item_codec_config; }
57
0
  std::vector<uint8_t> get_gainmap_item_codec_config() const { return m_gainmap_item_codec_config; }
58
59
99
  std::vector<uint8_t> get_icc_data() const { return m_icc_data; }
60
61
187
  uint64_t get_main_item_data_offset() const { return m_main_item_data_offset; }
62
187
  uint32_t get_main_item_data_size() const { return m_main_item_data_size; }
63
35
  uint64_t get_alpha_item_data_offset() const { return m_alpha_item_data_offset; }
64
1.16k
  uint32_t get_alpha_item_data_size() const { return m_alpha_item_data_size; }
65
108
  uint64_t get_exif_item_data_offset() const { return m_exif_item_data_offset; }
66
108
  uint32_t get_exif_item_data_size() const { return m_exif_data_size; }
67
118
  uint64_t get_xmp_item_data_offset() const { return m_xmp_item_data_offset; }
68
118
  uint32_t get_xmp_item_data_size() const { return m_xmp_data_size; }
69
70
189
  uint16_t get_colour_primaries() const { return m_colour_primaries; }
71
189
  uint16_t get_transfer_characteristics() const { return m_transfer_characteristics; }
72
189
  uint16_t get_matrix_coefficients() const { return m_matrix_coefficients; }
73
189
  bool get_full_range_flag() const { return m_full_range_flag; }
74
75
  // --- Setters (for write path) ---
76
77
0
  void set_version(uint8_t v) { m_version = v; }
78
0
  void set_explicit_codec_types_flag(bool f) { m_explicit_codec_types_flag = f; }
79
0
  void set_float_flag(bool f) { m_float_flag = f; }
80
0
  void set_full_range_flag(bool f) { m_full_range_flag = f; }
81
0
  void set_alpha_flag(bool f) { m_alpha_flag = f; }
82
0
  void set_explicit_cicp_flag(bool f) { m_explicit_cicp_flag = f; }
83
0
  void set_hdr_flag(bool f) { m_hdr_flag = f; }
84
0
  void set_icc_flag(bool f) { m_icc_flag = f; }
85
0
  void set_exif_flag(bool f) { m_exif_flag = f; }
86
0
  void set_xmp_flag(bool f) { m_xmp_flag = f; }
87
0
  void set_chroma_subsampling(uint8_t cs) { m_chroma_subsampling = cs; }
88
0
  void set_orientation(uint8_t o) { m_orientation = o; }
89
0
  void set_width(uint32_t w) { m_width = w; }
90
0
  void set_height(uint32_t h) { m_height = h; }
91
0
  void set_bit_depth(uint8_t bd) { m_bit_depth = bd; }
92
0
  void set_chroma_is_horizontally_centered(bool f) { m_chroma_is_horizontally_centered = f; }
93
0
  void set_chroma_is_vertically_centered(bool f) { m_chroma_is_vertically_centered = f; }
94
0
  void set_alpha_is_premultiplied(bool f) { m_alpha_is_premultiplied = f; }
95
0
  void set_colour_primaries(uint16_t cp) { m_colour_primaries = cp; }
96
0
  void set_transfer_characteristics(uint16_t tc) { m_transfer_characteristics = tc; }
97
0
  void set_matrix_coefficients(uint16_t mc) { m_matrix_coefficients = mc; }
98
0
  void set_infe_type(uint32_t t) { m_infe_type = t; }
99
0
  void set_codec_config_type(uint32_t t) { m_codec_config_type = t; }
100
0
  void set_exif_xmp_compressed_flag(bool f) { m_exif_xmp_compressed_flag = f; }
101
102
0
  void set_main_item_codec_config(std::vector<uint8_t> data) { m_main_item_codec_config = std::move(data); }
103
0
  void set_alpha_item_codec_config(std::vector<uint8_t> data) { m_alpha_item_codec_config = std::move(data); }
104
0
  void set_gainmap_item_codec_config(std::vector<uint8_t> data) { m_gainmap_item_codec_config = std::move(data); }
105
0
  void set_icc_data(std::vector<uint8_t> data) { m_icc_data = std::move(data); }
106
107
0
  void set_main_item_data(std::vector<uint8_t> data) { m_main_item_data = std::move(data); }
108
0
  void set_alpha_item_data(std::vector<uint8_t> data) { m_alpha_item_data = std::move(data); }
109
0
  void set_gainmap_item_data(std::vector<uint8_t> data) { m_gainmap_item_data = std::move(data); }
110
0
  void set_exif_data(std::vector<uint8_t> data) { m_exif_data_bytes = std::move(data); }
111
0
  void set_xmp_data(std::vector<uint8_t> data) { m_xmp_data_bytes = std::move(data); }
112
113
  // Gainmap setters
114
0
  void set_gainmap_flag(bool f) { m_gainmap_flag = f; }
115
0
  void set_gainmap_width(uint32_t w) { m_gainmap_width = w; }
116
0
  void set_gainmap_height(uint32_t h) { m_gainmap_height = h; }
117
0
  void set_gainmap_matrix_coefficients(uint8_t mc) { m_gainmap_matrix_coefficients = mc; }
118
0
  void set_gainmap_full_range_flag(bool f) { m_gainmap_full_range_flag = f; }
119
0
  void set_gainmap_chroma_subsampling(uint8_t cs) { m_gainmap_chroma_subsampling = cs; }
120
0
  void set_gainmap_float_flag(bool f) { m_gainmap_float_flag = f; }
121
0
  void set_gainmap_bit_depth(uint8_t bd) { m_gainmap_bit_depth = bd; }
122
0
  void set_tmap_icc_flag(bool f) { m_tmap_icc_flag = f; }
123
0
  void set_tmap_explicit_cicp_flag(bool f) { m_tmap_explicit_cicp_flag = f; }
124
0
  void set_tmap_colour_primaries(uint16_t cp) { m_tmap_colour_primaries = cp; }
125
0
  void set_tmap_transfer_characteristics(uint16_t tc) { m_tmap_transfer_characteristics = tc; }
126
0
  void set_tmap_matrix_coefficients(uint16_t mc) { m_tmap_matrix_coefficients = mc; }
127
0
  void set_tmap_full_range_flag(bool f) { m_tmap_full_range_flag = f; }
128
0
  void set_tmap_icc_data(std::vector<uint8_t> data) { m_tmap_icc_data = std::move(data); }
129
0
  void set_gainmap_metadata(std::vector<uint8_t> data) { m_gainmap_metadata = std::move(data); }
130
131
  // HDR metadata setters
132
0
  void set_clli(std::shared_ptr<Box_clli> box) { m_clli = std::move(box); }
133
0
  void set_mdcv(std::shared_ptr<Box_mdcv> box) { m_mdcv = std::move(box); }
134
0
  void set_cclv(std::shared_ptr<Box_cclv> box) { m_cclv = std::move(box); }
135
0
  void set_amve(std::shared_ptr<Box_amve> box) { m_amve = std::move(box); }
136
0
  void set_ndwt(std::shared_ptr<Box_ndwt> box) { m_ndwt = std::move(box); }
137
0
  void set_tmap_clli(std::shared_ptr<Box_clli> box) { m_tmap_clli = std::move(box); }
138
0
  void set_tmap_mdcv(std::shared_ptr<Box_mdcv> box) { m_tmap_mdcv = std::move(box); }
139
0
  void set_tmap_cclv(std::shared_ptr<Box_cclv> box) { m_tmap_cclv = std::move(box); }
140
0
  void set_tmap_amve(std::shared_ptr<Box_amve> box) { m_tmap_amve = std::move(box); }
141
0
  void set_tmap_ndwt(std::shared_ptr<Box_ndwt> box) { m_tmap_ndwt = std::move(box); }
142
143
  std::string dump(Indent &) const override;
144
145
  Error write(StreamWriter& writer) const override;
146
147
  // Check if a HeifFile can be represented as a mini box.
148
  // Returns true if conversion is possible. If false, out_reason explains why not.
149
  static bool can_convert_to_mini(const class HeifFile* file, std::string& out_reason);
150
151
  // Create a Box_mini from a HeifFile's meta box structure.
152
  // This is the inverse of create_expanded_boxes().
153
  // Returns nullptr if conversion is not possible.
154
  static std::shared_ptr<Box_mini> create_from_heif_file(class HeifFile* file);
155
156
  // Compose the cumulative EXIF-style orientation of a sequence of property
157
  // boxes by composing irot/imir transforms in list order via
158
  // heif_orientation_concat(). Non-transform properties are ignored.
159
  // Returns heif_orientation_normal (1) for an empty list.
160
  static heif_orientation compute_orientation_from_properties(
161
      const std::vector<std::shared_ptr<Box>>& properties);
162
163
protected:
164
  Error parse(BitstreamRange &range, const heif_security_limits *limits) override;
165
166
private:
167
  uint8_t m_version = 0;
168
  bool m_explicit_codec_types_flag = false;
169
  bool m_float_flag = false;
170
  bool m_full_range_flag = false;
171
  bool m_alpha_flag = false;
172
  bool m_explicit_cicp_flag = false;
173
  bool m_hdr_flag = false;
174
  bool m_icc_flag = false;
175
  bool m_exif_flag = false;
176
  bool m_xmp_flag = false;
177
  bool m_exif_xmp_compressed_flag = false; // when enabled, data is compressed with 'deflate'
178
  uint8_t m_chroma_subsampling = 0;
179
  uint8_t m_orientation = 0;
180
181
  uint32_t m_width = 0;
182
  uint32_t m_height = 0;
183
  uint8_t m_bit_depth = 8;
184
  bool m_chroma_is_horizontally_centered = false;
185
  bool m_chroma_is_vertically_centered = false;
186
  bool m_alpha_is_premultiplied = false;
187
  uint16_t m_colour_primaries = 0;
188
  uint16_t m_transfer_characteristics = 0;
189
  uint16_t m_matrix_coefficients = 0;
190
191
  uint32_t m_infe_type = 0;
192
  uint32_t m_codec_config_type = 0;
193
194
  bool m_gainmap_flag = false;
195
196
  uint32_t m_gainmap_width = 0;
197
  uint32_t m_gainmap_height = 0;
198
  uint8_t m_gainmap_matrix_coefficients = 0;
199
  bool m_gainmap_full_range_flag = false;
200
  uint8_t m_gainmap_chroma_subsampling = 0;
201
  bool m_gainmap_chroma_is_horizontally_centred = false;
202
  bool m_gainmap_chroma_is_vertically_centred = false;
203
  bool m_gainmap_float_flag = false;
204
  uint8_t m_gainmap_bit_depth = 8;
205
  bool m_tmap_icc_flag = false;
206
  bool m_tmap_explicit_cicp_flag = false;
207
  uint16_t m_tmap_colour_primaries = 0;
208
  uint16_t m_tmap_transfer_characteristics = 0;
209
  uint16_t m_tmap_matrix_coefficients = 0;
210
  bool m_tmap_full_range_flag = false;
211
212
  bool m_reve_flag = false;
213
  std::shared_ptr<Box_clli> m_clli;
214
  std::shared_ptr<Box_mdcv> m_mdcv;
215
  std::shared_ptr<Box_cclv> m_cclv;
216
  std::shared_ptr<Box_amve> m_amve;
217
  // std::shared_ptr<Box_reve> m_reve;
218
  std::shared_ptr<Box_ndwt> m_ndwt;
219
220
  bool m_tmap_reve_flag = false;
221
  std::shared_ptr<Box_clli> m_tmap_clli;
222
  std::shared_ptr<Box_mdcv> m_tmap_mdcv;
223
  std::shared_ptr<Box_cclv> m_tmap_cclv;
224
  std::shared_ptr<Box_amve> m_tmap_amve;
225
  // std::shared_ptr<Box_reve> m_tmap_reve;
226
  std::shared_ptr<Box_ndwt> m_tmap_ndwt;
227
228
  std::vector<uint8_t> m_alpha_item_codec_config;
229
  std::vector<uint8_t> m_gainmap_item_codec_config;
230
  std::vector<uint8_t> m_main_item_codec_config;
231
  std::vector<uint8_t> m_icc_data;
232
  std::vector<uint8_t> m_tmap_icc_data;
233
  std::vector<uint8_t> m_gainmap_metadata;
234
235
  uint64_t m_alpha_item_data_offset = 0;
236
  uint32_t m_alpha_item_data_size = 0;
237
  uint64_t m_main_item_data_offset = 0;
238
  uint32_t m_main_item_data_size = 0;
239
  uint64_t m_gainmap_item_data_offset = 0;
240
  uint32_t m_gainmap_item_data_size = 0;
241
  uint64_t m_exif_item_data_offset = 0;
242
  uint32_t m_exif_data_size = 0;
243
  uint64_t m_xmp_item_data_offset = 0;
244
  uint32_t m_xmp_data_size = 0;
245
246
  // Image data for write path (not populated during parse)
247
  std::vector<uint8_t> m_main_item_data;
248
  std::vector<uint8_t> m_alpha_item_data;
249
  std::vector<uint8_t> m_gainmap_item_data;
250
  std::vector<uint8_t> m_exif_data_bytes;
251
  std::vector<uint8_t> m_xmp_data_bytes;
252
};
253
254
#endif