Commit d07fb9cb for libheif
commit d07fb9cbfdaad84ec4b3a95d40ce7cca0d68db88
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Mon Jan 12 20:55:19 2026 +0100
implement 'sdtp' box (decoding for informational purpose only)
diff --git a/libheif/box.cc b/libheif/box.cc
index ceafd974..76ba0f0a 100644
--- a/libheif/box.cc
+++ b/libheif/box.cc
@@ -880,6 +880,10 @@ Error Box::read(BitstreamRange& range, std::shared_ptr<Box>* result, const heif_
box = std::make_shared<Box_tref>();
break;
+ case fourcc("sdtp"):
+ box = std::make_shared<Box_sdtp>();
+ break;
+
default:
box = std::make_shared<Box_other>(hdr.get_short_type());
break;
diff --git a/libheif/sequences/seq_boxes.cc b/libheif/sequences/seq_boxes.cc
index d9642c57..8f834c7c 100644
--- a/libheif/sequences/seq_boxes.cc
+++ b/libheif/sequences/seq_boxes.cc
@@ -2114,6 +2114,49 @@ Error Box_saio::parse(BitstreamRange& range, const heif_security_limits* limits)
}
+std::string Box_sdtp::dump(Indent& indent) const
+{
+ std::stringstream sstr;
+ sstr << FullBox::dump(indent);
+
+ assert(m_sample_information.size() <= UINT32_MAX);
+
+ for (uint32_t i = 0; i < static_cast<uint32_t>(m_sample_information.size()); i++) {
+ const char* spaces = " ";
+ int nSpaces = 6;
+ int k = i;
+ while (k >= 10 && nSpaces < 12) {
+ k /= 10;
+ nSpaces++;
+ }
+
+ spaces = spaces + 12 - nSpaces;
+
+ sstr << indent << "[" << i << "] : is_leading=" << (int) get_is_leading(i) << "\n"
+ << indent << spaces << "depends_on=" << (int) get_depends_on(i) << "\n"
+ << indent << spaces << "is_depended_on=" << (int) get_is_depended_on(i) << "\n"
+ << indent << spaces << "has_redundancy=" << (int) get_has_redundancy(i) << "\n";
+ }
+
+ return sstr.str();
+}
+
+
+Error Box_sdtp::parse(BitstreamRange& range, const heif_security_limits* limits)
+{
+ parse_full_box_header(range);
+
+ // We have no easy way to get the number of samples from 'saiz' or 'stz2' as specified
+ // in the standard. Instead, we read until the end of the box.
+ size_t nSamples = range.get_remaining_bytes();
+
+ m_sample_information.resize(nSamples);
+ range.read(m_sample_information.data(), nSamples);
+
+ return Error::Ok;
+}
+
+
Error Box_tref::parse(BitstreamRange& range, const heif_security_limits* limits)
{
while (!range.eof()) {
diff --git a/libheif/sequences/seq_boxes.h b/libheif/sequences/seq_boxes.h
index effcd5c5..b12350dc 100644
--- a/libheif/sequences/seq_boxes.h
+++ b/libheif/sequences/seq_boxes.h
@@ -910,6 +910,35 @@ private:
};
+class Box_sdtp : public FullBox {
+public:
+ Box_sdtp()
+ {
+ set_short_type(fourcc("sdtp"));
+ }
+
+ std::string dump(Indent&) const override;
+
+ const char* debug_box_name() const override { return "Independent and Disposable Samples"; }
+
+ // Error write(StreamWriter& writer) const override;
+
+ uint8_t get_is_leading(uint32_t sampleIdx) const { return (m_sample_information[sampleIdx] >> 6) & 3; }
+
+ uint8_t get_depends_on(uint32_t sampleIdx) const { return (m_sample_information[sampleIdx] >> 4) & 3; }
+
+ uint8_t get_is_depended_on(uint32_t sampleIdx) const { return (m_sample_information[sampleIdx] >> 2) & 3; }
+
+ uint8_t get_has_redundancy(uint32_t sampleIdx) const { return (m_sample_information[sampleIdx]) & 3; }
+
+protected:
+ Error parse(BitstreamRange& range, const heif_security_limits*) override;
+
+private:
+ std::vector<uint8_t> m_sample_information;
+};
+
+
class Box_tref : public Box
{
public: