Coverage Report

Created: 2025-10-10 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libheif/libheif/sequences/seq_boxes.h
Line
Count
Source
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2024 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 SEQ_BOXES_H
22
#define SEQ_BOXES_H
23
24
#include "box.h"
25
#include "security_limits.h"
26
27
#include <string>
28
#include <memory>
29
#include <vector>
30
31
32
class Box_container : public Box {
33
public:
34
  Box_container(const char* type)
35
6.44k
  {
36
6.44k
    set_short_type(fourcc(type));
37
6.44k
  }
38
39
  std::string dump(Indent&) const override;
40
41
protected:
42
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
43
};
44
45
46
// Movie Box
47
class Box_moov : public Box_container {
48
public:
49
5.37k
  Box_moov() : Box_container("moov") {}
50
51
168
  const char* debug_box_name() const override { return "Movie"; }
52
};
53
54
55
// Movie Header Box
56
class Box_mvhd : public FullBox {
57
public:
58
  Box_mvhd()
59
1.33k
  {
60
1.33k
    set_short_type(fourcc("mvhd"));
61
1.33k
  }
62
63
  std::string dump(Indent&) const override;
64
65
1.31k
  const char* debug_box_name() const override { return "Movie Header"; }
66
67
  Error write(StreamWriter& writer) const override;
68
69
  void derive_box_version() override;
70
71
1.31k
  double get_rate() const { return m_rate / double(0x10000); }
72
73
1.31k
  float get_volume() const { return float(m_volume) / float(0x100); }
74
75
  double get_matrix_element(int idx) const;
76
77
0
  uint32_t get_time_scale() const { return m_timescale; }
78
79
0
  uint64_t get_duration() const { return m_duration; }
80
81
0
  void set_duration(uint64_t duration) { m_duration = duration; }
82
83
0
  void set_time_scale(uint32_t timescale) { m_timescale = timescale; }
84
85
0
  void set_next_track_id(uint32_t next_id) { m_next_track_ID = next_id; }
86
87
protected:
88
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
89
90
private:
91
  uint64_t m_creation_time = 0;
92
  uint64_t m_modification_time = 0;
93
  uint32_t m_timescale = 0;
94
  uint64_t m_duration = 0;
95
96
  uint32_t m_rate = 0x00010000; // typically 1.0
97
  uint16_t m_volume = 0x0100; // typically, full volume
98
99
  uint32_t m_matrix[9] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
100
  uint32_t m_next_track_ID = 0;
101
};
102
103
104
// Track Box
105
class Box_trak : public Box_container {
106
public:
107
423
  Box_trak() : Box_container("trak") {}
108
109
322
  const char* debug_box_name() const override { return "Track"; }
110
};
111
112
113
// Track Header Box
114
class Box_tkhd : public FullBox {
115
public:
116
  Box_tkhd()
117
330
  {
118
330
    set_short_type(fourcc("tkhd"));
119
120
    // set default flags according to ISO 14496-12
121
330
    set_flags(Track_enabled | Track_in_movie | Track_in_preview);
122
330
  }
123
124
  enum Flags {
125
    Track_enabled = 0x01,
126
    Track_in_movie = 0x02,
127
    Track_in_preview = 0x04,
128
    Track_size_is_aspect_ratio = 0x08
129
  };
130
131
  std::string dump(Indent&) const override;
132
133
281
  const char* debug_box_name() const override { return "Track Header"; }
134
135
  Error write(StreamWriter& writer) const override;
136
137
  void derive_box_version() override;
138
139
281
  float get_volume() const { return float(m_volume) / float(0x100); }
140
141
  double get_matrix_element(int idx) const;
142
143
281
  double get_width() const { return float(m_width) / double(0x10000); }
144
145
281
  double get_height() const { return float(m_height) / double(0x10000); }
146
147
0
  uint32_t get_track_id() const { return m_track_id; }
148
149
0
  void set_track_id(uint32_t track_id) { m_track_id = track_id; }
150
151
  void set_resolution(double width, double height)
152
0
  {
153
0
    m_width = (uint32_t) (width * 0x10000);
154
0
    m_height = (uint32_t) (height * 0x10000);
155
0
  }
156
157
0
  uint64_t get_duration() const { return m_duration; }
158
159
0
  void set_duration(uint64_t duration) { m_duration = duration; }
160
161
protected:
162
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
163
164
private:
165
  uint64_t m_creation_time = 0;
166
  uint64_t m_modification_time = 0;
167
  uint32_t m_track_id = 0;
168
  uint64_t m_duration = 0;
169
170
  uint16_t m_layer = 0;
171
  uint16_t m_alternate_group = 0;
172
  uint16_t m_volume = 0x0100; // typically, full volume
173
174
  uint32_t m_matrix[9] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
175
176
  uint32_t m_width = 0;
177
  uint32_t m_height = 0;
178
};
179
180
181
// Media Box
182
class Box_mdia : public Box_container {
183
public:
184
51
  Box_mdia() : Box_container("mdia") {}
185
186
50
  const char* debug_box_name() const override { return "Media"; }
187
};
188
189
190
// Media Header Box
191
class Box_mdhd : public FullBox {
192
public:
193
  Box_mdhd()
194
279
  {
195
279
    set_short_type(fourcc("mdhd"));
196
279
  }
197
198
  std::string dump(Indent&) const override;
199
200
218
  const char* debug_box_name() const override { return "Media Header"; }
201
202
  Error write(StreamWriter& writer) const override;
203
204
  void derive_box_version() override;
205
206
  double get_matrix_element(int idx) const;
207
208
0
  uint32_t get_timescale() const { return m_timescale; }
209
210
0
  void set_timescale(uint32_t timescale) { m_timescale = timescale; }
211
212
0
  uint64_t get_duration() const { return m_duration; }
213
214
0
  void set_duration(uint64_t duration) { m_duration = duration; }
215
216
protected:
217
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
218
219
private:
220
  uint64_t m_creation_time = 0;
221
  uint64_t m_modification_time = 0;
222
  uint32_t m_timescale = 0;
223
  uint64_t m_duration = 0;
224
225
  char m_language[4] = {'u', 'n', 'k', 0};
226
};
227
228
229
// Media Information Box (container)
230
class Box_minf : public Box_container {
231
public:
232
184
  Box_minf() : Box_container("minf") {}
233
234
138
  const char* debug_box_name() const override { return "Media Information"; }
235
};
236
237
238
// Video Media Header
239
class Box_vmhd : public FullBox {
240
public:
241
  Box_vmhd()
242
412
  {
243
412
    set_short_type(fourcc("vmhd"));
244
412
    set_flags(1);
245
412
  }
246
247
  std::string dump(Indent&) const override;
248
249
217
  const char* debug_box_name() const override { return "Video Media Header"; }
250
251
  Error write(StreamWriter& writer) const override;
252
253
protected:
254
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
255
256
private:
257
  uint16_t m_graphics_mode = 0;
258
  uint16_t m_op_color[3] = {0, 0, 0};
259
};
260
261
262
// Null Media Header
263
class Box_nmhd : public FullBox {
264
public:
265
  Box_nmhd()
266
105
  {
267
105
    set_short_type(fourcc("nmhd"));
268
105
    set_flags(1);
269
105
  }
270
271
  std::string dump(Indent&) const override;
272
273
105
  const char* debug_box_name() const override { return "Null Media Header"; }
274
275
  Error write(StreamWriter& writer) const override;
276
277
protected:
278
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
279
};
280
281
282
// Sample Table Box (container)
283
class Box_stbl : public Box_container {
284
public:
285
328
  Box_stbl() : Box_container("stbl") {}
286
287
285
  const char* debug_box_name() const override { return "Sample Table"; }
288
};
289
290
291
// Sample Description Box
292
class Box_stsd : public FullBox {
293
public:
294
  Box_stsd()
295
372
  {
296
372
    set_short_type(fourcc("stsd"));
297
372
  }
298
299
  std::string dump(Indent&) const override;
300
301
250
  const char* debug_box_name() const override { return "Sample Description"; }
302
303
  Error write(StreamWriter& writer) const override;
304
305
  std::shared_ptr<const class Box> get_sample_entry(size_t idx) const
306
0
  {
307
0
    if (idx >= m_sample_entries.size()) {
308
0
      return nullptr;
309
0
    } else {
310
0
      return m_sample_entries[idx];
311
0
    }
312
0
  }
313
314
  void add_sample_entry(std::shared_ptr<class Box> entry)
315
0
  {
316
0
    m_sample_entries.push_back(entry);
317
0
  }
318
319
0
  size_t get_num_sample_entries() const { return m_sample_entries.size(); }
320
321
protected:
322
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
323
324
private:
325
  std::vector<std::shared_ptr<class Box>> m_sample_entries;
326
};
327
328
329
// Decoding Time to Sample Box
330
class Box_stts : public FullBox {
331
public:
332
  Box_stts()
333
301
  {
334
301
    set_short_type(fourcc("stts"));
335
301
  }
336
337
  std::string dump(Indent&) const override;
338
339
266
  const char* debug_box_name() const override { return "Decoding Time to Sample"; }
340
341
  Error write(StreamWriter& writer) const override;
342
343
  struct TimeToSample {
344
    uint32_t sample_count;
345
    uint32_t sample_delta;
346
  };
347
348
  uint32_t get_sample_duration(uint32_t sample_idx);
349
350
  void append_sample_duration(uint32_t duration);
351
352
  uint64_t get_total_duration(bool include_last_frame_duration);
353
354
protected:
355
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
356
357
private:
358
  std::vector<TimeToSample> m_entries;
359
  MemoryHandle m_memory_handle;
360
};
361
362
363
// Sample to Chunk Box
364
class Box_stsc : public FullBox {
365
public:
366
  Box_stsc()
367
1.24k
  {
368
1.24k
    set_short_type(fourcc("stsc"));
369
1.24k
  }
370
371
  std::string dump(Indent&) const override;
372
373
934
  const char* debug_box_name() const override { return "Sample to Chunk"; }
374
375
  Error write(StreamWriter& writer) const override;
376
377
  struct SampleToChunk {
378
    uint32_t first_chunk;
379
    uint32_t samples_per_chunk;
380
    uint32_t sample_description_index;
381
  };
382
383
0
  const std::vector<SampleToChunk>& get_chunks() const { return m_entries; }
384
385
  // idx counting starts at 1
386
  const SampleToChunk* get_chunk(uint32_t idx) const;
387
388
  void add_chunk(uint32_t description_index);
389
390
  void increase_samples_in_chunk(uint32_t nFrames);
391
392
0
  bool last_chunk_empty() const {
393
0
    assert(!m_entries.empty());
394
395
0
    return m_entries.back().samples_per_chunk == 0;
396
0
  }
397
398
protected:
399
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
400
401
private:
402
  std::vector<SampleToChunk> m_entries;
403
  MemoryHandle m_memory_handle;
404
};
405
406
407
// Chunk Offset Box
408
class Box_stco : public FullBox {
409
public:
410
  Box_stco()
411
1.08k
  {
412
1.08k
    set_short_type(fourcc("stco"));
413
1.08k
  }
414
415
  std::string dump(Indent&) const override;
416
417
1.07k
  const char* debug_box_name() const override { return "Sample Offset"; }
418
419
  Error write(StreamWriter& writer) const override;
420
421
0
  void add_chunk_offset(uint32_t offset) { m_offsets.push_back(offset); }
422
423
0
  const std::vector<uint32_t>& get_offsets() const { return m_offsets; }
424
425
  void patch_file_pointers(StreamWriter&, size_t offset) override;
426
427
protected:
428
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
429
430
private:
431
  std::vector<uint32_t> m_offsets;
432
  MemoryHandle m_memory_handle;
433
434
  mutable size_t m_offset_start_pos = 0;
435
};
436
437
438
// Sample Size Box
439
class Box_stsz : public FullBox {
440
public:
441
  Box_stsz()
442
2.79k
  {
443
2.79k
    set_short_type(fourcc("stsz"));
444
2.79k
  }
445
446
  std::string dump(Indent&) const override;
447
448
1.66k
  const char* debug_box_name() const override { return "Sample Size"; }
449
450
  Error write(StreamWriter& writer) const override;
451
452
0
  bool has_fixed_sample_size() const { return m_fixed_sample_size != 0; }
453
454
0
  uint32_t get_fixed_sample_size() const { return m_fixed_sample_size; }
455
456
0
  uint32_t num_samples() const { return m_sample_count; }
457
458
0
  const std::vector<uint32_t>& get_sample_sizes() const { return m_sample_sizes; }
459
460
  void append_sample_size(uint32_t size);
461
462
protected:
463
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
464
465
private:
466
  uint32_t m_fixed_sample_size = 0;
467
  uint32_t m_sample_count = 0;
468
  std::vector<uint32_t> m_sample_sizes;
469
  MemoryHandle m_memory_handle;
470
};
471
472
473
// Sync Sample Box
474
class Box_stss : public FullBox {
475
public:
476
  Box_stss()
477
345
  {
478
345
    set_short_type(fourcc("stss"));
479
345
  }
480
481
  std::string dump(Indent&) const override;
482
483
165
  const char* debug_box_name() const override { return "Sync Sample"; }
484
485
  Error write(StreamWriter& writer) const override;
486
487
0
  void add_sync_sample(uint32_t sample_idx) { m_sync_samples.push_back(sample_idx); }
488
489
protected:
490
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
491
492
private:
493
  std::vector<uint32_t> m_sync_samples;
494
  MemoryHandle m_memory_handle;
495
};
496
497
498
struct CodingConstraints {
499
  bool all_ref_pics_intra = false;
500
  bool intra_pred_used = false;
501
  uint8_t max_ref_per_pic = 0; // 4 bit
502
};
503
504
505
// Coding Constraints Box
506
class Box_ccst : public FullBox {
507
public:
508
  Box_ccst()
509
367
  {
510
367
    set_short_type(fourcc("ccst"));
511
367
  }
512
513
  std::string dump(Indent&) const override;
514
515
367
  const char* debug_box_name() const override { return "Coding Constraints"; }
516
517
  Error write(StreamWriter& writer) const override;
518
519
0
  void set_coding_constraints(const CodingConstraints& c) { m_codingConstraints = c; }
520
521
0
  const CodingConstraints& get_coding_constraints() const { return m_codingConstraints; }
522
523
protected:
524
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
525
526
private:
527
  CodingConstraints m_codingConstraints;
528
};
529
530
531
class Box_auxi : public FullBox {
532
public:
533
  Box_auxi()
534
280
  {
535
280
    set_short_type(fourcc("auxi"));
536
280
  }
537
538
  std::string dump(Indent&) const override;
539
540
279
  const char* debug_box_name() const override { return "Auxiliary Info Type"; }
541
542
  Error write(StreamWriter& writer) const override;
543
544
0
  void set_aux_track_type_urn(const std::string& t) { m_aux_track_type = t; }
545
546
0
  std::string get_aux_track_type_urn() const { return m_aux_track_type; }
547
548
protected:
549
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
550
551
private:
552
  std::string m_aux_track_type;
553
};
554
555
556
struct VisualSampleEntry {
557
  // from SampleEntry
558
  //const unsigned int(8)[6] reserved = 0;
559
  uint16_t data_reference_index;
560
561
  // VisualSampleEntry
562
563
  uint16_t pre_defined = 0;
564
  //uint16_t reserved = 0;
565
  uint32_t pre_defined2[3] = {0, 0, 0};
566
  uint16_t width = 0;
567
  uint16_t height = 0;
568
  uint32_t horizresolution = 0x00480000; // 72 dpi
569
  uint32_t vertresolution = 0x00480000; // 72 dpi
570
  //uint32_t reserved = 0;
571
  uint16_t frame_count = 1;
572
  std::string compressorname; // max 32 characters
573
  uint16_t depth = 0x0018;
574
  int16_t pre_defined3 = -1;
575
  // other boxes from derived specifications
576
  //std::shared_ptr<Box_clap> clap; // optional
577
  //std::shared_ptr<Box_pixi> pixi; // optional
578
579
1.02k
  double get_horizontal_resolution() const { return horizresolution / double(0x10000); }
580
581
1.02k
  double get_vertical_resolution() const { return vertresolution / double(0x10000); }
582
583
  Error parse(BitstreamRange& range, const heif_security_limits*);
584
585
  Error write(StreamWriter& writer) const;
586
587
  std::string dump(Indent&) const;
588
};
589
590
591
class Box_VisualSampleEntry : public Box {
592
public:
593
  Error write(StreamWriter& writer) const override;
594
595
  std::string dump(Indent&) const override;
596
597
0
  const VisualSampleEntry& get_VisualSampleEntry_const() const { return m_visualSampleEntry; }
598
599
0
  VisualSampleEntry& get_VisualSampleEntry() { return m_visualSampleEntry; }
600
601
protected:
602
  Error parse(BitstreamRange& range, const heif_security_limits* limits) override;
603
604
private:
605
  VisualSampleEntry m_visualSampleEntry;
606
};
607
608
609
class Box_URIMetaSampleEntry : public Box {
610
public:
611
  Box_URIMetaSampleEntry()
612
404
  {
613
404
    set_short_type(fourcc("urim"));
614
404
  }
615
616
  Error write(StreamWriter& writer) const override;
617
618
  std::string dump(Indent&) const override;
619
620
378
  const char* debug_box_name() const override { return "URI Meta Sample Entry"; }
621
622
protected:
623
  Error parse(BitstreamRange& range, const heif_security_limits* limits) override;
624
625
private:
626
  // from SampleEntry
627
  //const unsigned int(8)[6] reserved = 0;
628
  uint16_t data_reference_index;
629
};
630
631
632
class Box_uri : public FullBox {
633
public:
634
  Box_uri()
635
702
  {
636
702
    set_short_type(fourcc("uri "));
637
702
  }
638
639
0
  void set_uri(std::string uri) { m_uri = uri; }
640
641
0
  std::string get_uri() const { return m_uri; }
642
643
  Error write(StreamWriter& writer) const override;
644
645
  std::string dump(Indent&) const override;
646
647
523
  const char* debug_box_name() const override { return "URI"; }
648
649
protected:
650
  Error parse(BitstreamRange& range, const heif_security_limits* limits) override;
651
652
private:
653
  std::string m_uri;
654
};
655
656
657
// Sample to Group
658
class Box_sbgp : public FullBox {
659
public:
660
  Box_sbgp()
661
265
  {
662
265
    set_short_type(fourcc("sbgp"));
663
265
  }
664
665
  void derive_box_version() override;
666
667
  std::string dump(Indent&) const override;
668
669
227
  const char* debug_box_name() const override { return "Sample to Group"; }
670
671
  Error write(StreamWriter& writer) const override;
672
673
protected:
674
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
675
676
private:
677
  uint32_t m_grouping_type = 0; // 4cc
678
  std::optional<uint32_t> m_grouping_type_parameter;
679
680
  struct Entry {
681
    uint32_t sample_count;
682
    uint32_t group_description_index;
683
  };
684
685
  std::vector<Entry> m_entries;
686
  MemoryHandle m_memory_handle;
687
};
688
689
690
class SampleGroupEntry
691
{
692
public:
693
87.9k
  virtual ~SampleGroupEntry() = default;
694
695
  virtual std::string dump() const = 0;
696
697
  virtual Error write(StreamWriter& writer) const = 0;
698
699
  virtual Error parse(BitstreamRange& range, const heif_security_limits*) = 0;
700
};
701
702
703
class SampleGroupEntry_refs : public SampleGroupEntry
704
{
705
public:
706
  std::string dump() const override;
707
708
  Error write(StreamWriter& writer) const override;
709
710
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
711
712
private:
713
  uint32_t m_sample_id;
714
  std::vector<uint32_t> m_direct_reference_sample_id;
715
};
716
717
718
// Sample Group Description
719
class Box_sgpd : public FullBox {
720
public:
721
  Box_sgpd()
722
1.24k
  {
723
1.24k
    set_short_type(fourcc("sgpd"));
724
1.24k
  }
725
726
  void derive_box_version() override;
727
728
  std::string dump(Indent&) const override;
729
730
554
  const char* debug_box_name() const override { return "Sample Group Description"; }
731
732
  Error write(StreamWriter& writer) const override;
733
734
protected:
735
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
736
737
private:
738
  uint32_t m_grouping_type = 0; // 4cc
739
  std::optional<uint32_t> m_default_length; // version 1  (0 -> variable length)
740
  std::optional<uint32_t> m_default_sample_description_index;; // version >= 2
741
742
  struct Entry {
743
    uint32_t description_length = 0; // if version==1 && m_default_length == 0
744
    std::shared_ptr<SampleGroupEntry> sample_group_entry;
745
  };
746
747
  std::vector<Entry> m_entries;
748
};
749
750
// Bitrate
751
class Box_btrt : public FullBox {
752
public:
753
  Box_btrt()
754
345
  {
755
345
    set_short_type(fourcc("btrt"));
756
345
  }
757
758
  std::string dump(Indent&) const override;
759
760
310
  const char* debug_box_name() const override { return "Bitrate"; }
761
762
  Error write(StreamWriter& writer) const override;
763
764
protected:
765
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
766
767
private:
768
  uint32_t m_bufferSizeDB;
769
  uint32_t m_maxBitrate;
770
  uint32_t m_avgBitrate;
771
};
772
773
774
class Box_saiz : public FullBox {
775
public:
776
  Box_saiz()
777
565
  {
778
565
    set_short_type(fourcc("saiz"));
779
565
  }
780
781
  void set_aux_info_type(uint32_t aux_info_type, uint32_t aux_info_type_parameter = 0);
782
783
0
  uint32_t get_aux_info_type() const { return m_aux_info_type; }
784
785
0
  uint32_t get_aux_info_type_parameter() const { return m_aux_info_type_parameter; }
786
787
  void add_sample_size(uint8_t s);
788
789
0
  void add_nonpresent_sample() { add_sample_size(0); }
790
791
  uint8_t get_sample_size(uint32_t idx);
792
793
0
  uint32_t get_num_samples() const { return m_num_samples; }
794
795
  std::string dump(Indent&) const override;
796
797
291
  const char* debug_box_name() const override { return "Sample Auxiliary Information Sizes"; }
798
799
  Error write(StreamWriter& writer) const override;
800
801
protected:
802
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
803
804
private:
805
  uint32_t m_aux_info_type = 0;
806
  uint32_t m_aux_info_type_parameter = 0;
807
  uint8_t  m_default_sample_info_size = 0;  // 0 -> variable length
808
  uint32_t m_num_samples = 0; // needed in case we are using the default sample size
809
810
  std::vector<uint8_t> m_sample_sizes;
811
  MemoryHandle m_memory_handle;
812
};
813
814
815
class Box_saio : public FullBox {
816
public:
817
  Box_saio()
818
295
  {
819
295
    set_short_type(fourcc("saio"));
820
295
  }
821
822
  void set_aux_info_type(uint32_t aux_info_type, uint32_t aux_info_type_parameter = 0);
823
824
0
  uint32_t get_aux_info_type() const { return m_aux_info_type; }
825
826
0
  uint32_t get_aux_info_type_parameter() const { return m_aux_info_type_parameter; }
827
828
  void add_sample_offset(uint64_t offset);
829
830
  // This will be 1 if all infos are written contiguously
831
0
  size_t get_num_samples() const { return m_sample_offset.size(); }
832
833
  uint64_t get_sample_offset(uint32_t idx) const;
834
835
  std::string dump(Indent&) const override;
836
837
284
  const char* debug_box_name() const override { return "Sample Auxiliary Information Offsets"; }
838
839
  Error write(StreamWriter& writer) const override;
840
841
protected:
842
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
843
844
  void patch_file_pointers(StreamWriter& writer, size_t offset) override;
845
846
private:
847
  uint32_t m_aux_info_type = 0;
848
  uint32_t m_aux_info_type_parameter = 0;
849
850
  bool m_need_64bit = false;
851
  mutable uint64_t m_offset_start_pos;
852
853
  // If sample_offset==1, all samples are stored contiguous in the file
854
  std::vector<uint64_t> m_sample_offset;
855
856
  MemoryHandle m_memory_handle;
857
};
858
859
860
class Box_tref : public Box
861
{
862
public:
863
  Box_tref()
864
341
  {
865
341
    set_short_type(fourcc("tref"));
866
341
  }
867
868
  struct Reference {
869
    uint32_t reference_type;
870
    std::vector<uint32_t> to_track_id;
871
  };
872
873
  std::string dump(Indent&) const override;
874
875
218
  const char* debug_box_name() const override { return "Track Reference"; }
876
877
  std::vector<uint32_t> get_references(uint32_t ref_type) const;
878
879
  size_t get_number_of_references_of_type(uint32_t ref_type) const;
880
881
0
  size_t get_number_of_reference_types() const { return m_references.size(); }
882
883
  std::vector<uint32_t> get_reference_types() const;
884
885
  void add_references(uint32_t to_track_id, uint32_t type);
886
887
protected:
888
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
889
890
  Error write(StreamWriter& writer) const override;
891
892
  Error check_for_double_references() const;
893
894
private:
895
  std::vector<Reference> m_references;
896
};
897
898
899
// Edit List container
900
class Box_edts : public Box_container {
901
public:
902
92
  Box_edts() : Box_container("edts") {}
903
904
60
  const char* debug_box_name() const override { return "Edit List Container"; }
905
};
906
907
908
class Box_elst : public FullBox
909
{
910
public:
911
  Box_elst()
912
299
  {
913
299
    set_short_type(fourcc("elst"));
914
299
  }
915
916
  enum Flags {
917
    Repeat_EditList = 0x01
918
  };
919
920
  std::string dump(Indent&) const override;
921
922
257
  const char* debug_box_name() const override { return "Edit List"; }
923
924
  void enable_repeat_mode(bool enable);
925
926
0
  bool is_repeat_mode() const { return get_flags() & Flags::Repeat_EditList; }
927
928
  struct Entry {
929
    uint64_t segment_duration = 0;
930
    int64_t media_time = 0;
931
    int16_t media_rate_integer = 1;
932
    int16_t media_rate_fraction = 0;
933
  };
934
935
  void add_entry(const Entry&);
936
937
0
  size_t num_entries() const { return m_entries.size(); }
938
939
0
  Entry get_entry(uint32_t entry) const { return m_entries[entry]; }
940
941
protected:
942
  Error parse(BitstreamRange& range, const heif_security_limits*) override;
943
944
  Error write(StreamWriter& writer) const override;
945
946
public:
947
  void derive_box_version() override;
948
949
private:
950
  std::vector<Entry> m_entries;
951
};
952
953
#endif //SEQ_BOXES_H