Commit d7165301 for libheif

commit d7165301b9605539b5b0e4030d9f86362b144250
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Mon Oct 5 13:56:27 2026 +0200

    Pass the output stream to Box::dump() instead of returning a string

    dump() built a std::string in every box and returned it, and each
    container re-appended and re-copied its children's strings at every
    nesting level. Dumping a deeply nested box therefore copied the whole
    subtree once per level, which is quadratic in the nesting depth.

    dump() now takes the std::ostream it writes into, so the whole box tree
    is written into a single buffer in one pass without the per-level
    copies. Box::dump_to_string() is a convenience wrapper for the callers
    that want the dump as a string (heif-info, the tests, the fuzzer).

    Because all boxes now share one stream, a sticky stream modifier (such
    as std::hex for a FullBox flags field) would leak from one box into the
    next. reset_stream_format() resets the stream to our defaults (decimal,
    blank fill) between boxes, and FullBox::dump() restores decimal right
    after printing its flags, so each box is formatted independently as
    before.

    A bool full_log parameter is threaded through dump() but not yet used;
    the following commit uses it to bound the output of the boxes whose
    content scales with the file size.

diff --git a/fuzzing/box_fuzzer.cc b/fuzzing/box_fuzzer.cc
index 114c8dc5..c74f8bbf 100644
--- a/fuzzing/box_fuzzer.cc
+++ b/fuzzing/box_fuzzer.cc
@@ -47,7 +47,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
     box->get_type();
     box->get_type_string();
     Indent indent;
-    box->dump(indent);
+    box->dump_to_string(indent);
   }

   return 0;
diff --git a/libheif/box.cc b/libheif/box.cc
index d096afe9..cac44658 100644
--- a/libheif/box.cc
+++ b/libheif/box.cc
@@ -404,9 +404,8 @@ Error Box::write_header(StreamWriter& writer, size_t total_size, bool data64bit)
 }


-std::string BoxHeader::dump(Indent& indent) const
+void BoxHeader::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
   sstr << indent << "Box: " << get_type_string();
   const char* debug_name = debug_box_name();
   if (debug_name) {
@@ -418,7 +417,7 @@ std::string BoxHeader::dump(Indent& indent) const

   sstr << indent << "size: " << get_box_size() << "   (header size: " << get_header_size() << ")\n";

-  return sstr.str();
+  return;
 }


@@ -1025,26 +1024,24 @@ Error Box::read(BitstreamRange& range, std::shared_ptr<Box>* result, const heif_
 }


-std::string Box::dump(Indent& indent) const
+void Box::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << BoxHeader::dump(indent);
+  BoxHeader::dump(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


-std::string FullBox::dump(Indent& indent) const
+void FullBox::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "version: " << ((int) m_version) << "\n"
-       << indent << "flags: " << std::hex << m_flags << "\n";
+       << indent << "flags: " << std::hex << m_flags << std::dec << "\n";

-  return sstr.str();
+  return;
 }


@@ -1212,10 +1209,8 @@ Error Box::write_children(StreamWriter& writer) const
 }


-std::string Box::dump_children(Indent& indent, bool with_index) const
+void Box::dump_children(std::ostream& sstr, Indent& indent, bool full_log, bool with_index) const
 {
-  std::ostringstream sstr;
-
   bool first = true;
   int idx=1;

@@ -1233,11 +1228,10 @@ std::string Box::dump_children(Indent& indent, bool with_index) const
       idx++;
     }

-    sstr << childBox->dump(indent);
+    childBox->dump(sstr, indent, full_log);
+    reset_stream_format(sstr);
   }
   indent--;
-
-  return sstr.str();
 }


@@ -1307,11 +1301,10 @@ Error Box_other::write(StreamWriter& writer) const
 }


-std::string Box_other::dump(Indent& indent) const
+void Box_other::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << BoxHeader::dump(indent);
+  BoxHeader::dump(sstr, indent, full_log);

   // --- show raw box content

@@ -1322,20 +1315,19 @@ std::string Box_other::dump(Indent& indent) const
   }
   else {
     sstr << indent << "invalid box size " << get_box_size() << " (smaller than header)\n";
-    return sstr.str();
+    return;
   }

   sstr << write_raw_data_as_hex(m_data.data(), len,
                                 indent.get_string() + "data: ",
                                 indent.get_string() + "      ");

-  return sstr.str();
+  return;
 }


-std::string Box_Error::dump(Indent& indent) const
+void Box_Error::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
   sstr << indent << '\'' << fourcc_to_string(m_box_type_with_parse_error) << "' parse error: " << m_error.message << "\n";
   sstr << indent << "fatality: ";
   switch (m_fatality) {
@@ -1344,7 +1336,7 @@ std::string Box_Error::dump(Indent& indent) const
     case parse_error_fatality::optional: sstr << "optional\n"; break;
   }

-  return sstr.str();
+  return;
 }

 parse_error_fatality Box_Error::get_parse_error_fatality() const
@@ -1393,11 +1385,10 @@ bool Box_ftyp::has_compatible_brand(heif_brand2 brand) const
 }


-std::string Box_ftyp::dump(Indent& indent) const
+void Box_ftyp::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << BoxHeader::dump(indent);
+  BoxHeader::dump(sstr, indent, full_log);

   sstr << indent << "major brand: " << fourcc_to_string(m_major_brand) << "\n"
        << indent << "minor version: ";
@@ -1419,7 +1410,7 @@ std::string Box_ftyp::dump(Indent& indent) const
   }
   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -1455,11 +1446,10 @@ Error Box_free::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_free::dump(Indent& indent) const
+void Box_free::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << BoxHeader::dump(indent);
-  return sstr.str();
+  BoxHeader::dump(sstr, indent, full_log);
+  return;
 }


@@ -1493,13 +1483,12 @@ Error Box_meta::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_meta::dump(Indent& indent) const
+void Box_meta::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << dump_children(indent);
+  Box::dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -1535,15 +1524,14 @@ Error Box_hdlr::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_hdlr::dump(Indent& indent) const
+void Box_hdlr::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "pre_defined: " << m_pre_defined << "\n"
        << indent << "handler_type: " << fourcc_to_string(m_handler_type) << "\n"
        << indent << "name: " << m_name << "\n";

-  return sstr.str();
+  return;
 }


@@ -1586,13 +1574,12 @@ Error Box_pitm::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_pitm::dump(Indent& indent) const
+void Box_pitm::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "item_ID: " << m_item_ID << "\n";

-  return sstr.str();
+  return;
 }


@@ -1804,10 +1791,9 @@ void Box_iloc::set_use_tmp_file(bool flag)
 }


-std::string Box_iloc::dump(Indent& indent) const
+void Box_iloc::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const Item& item : m_items) {
     sstr << indent << "item ID: " << item.item_ID << "\n"
@@ -1827,7 +1813,7 @@ std::string Box_iloc::dump(Indent& indent) const
     sstr << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -2628,10 +2614,9 @@ Error Box_infe::write(StreamWriter& writer) const
 }


-std::string Box_infe::dump(Indent& indent) const
+void Box_infe::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "item_ID: " << m_item_ID << "\n"
        << indent << "item_protection_index: " << m_item_protection_index << "\n"
@@ -2649,7 +2634,7 @@ std::string Box_infe::dump(Indent& indent) const

   sstr << indent << "hidden item: " << std::boolalpha << m_hidden_item << "\n";

-  return sstr.str();
+  return;
 }


@@ -2691,14 +2676,13 @@ Error Box_iinf::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_iinf::dump(Indent& indent) const
+void Box_iinf::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

-  sstr << dump_children(indent);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -2738,14 +2722,13 @@ Error Box_iinf::write(StreamWriter& writer) const
 }


-std::string Box_iprp::dump(Indent& indent) const
+void Box_iprp::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

-  sstr << dump_children(indent);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -2768,14 +2751,13 @@ Error Box_ipco::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ipco::dump(Indent& indent) const
+void Box_ipco::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

-  sstr << dump_children(indent, true);
+  dump_children(sstr, indent, full_log, true);

-  return sstr.str();
+  return;
 }


@@ -2805,10 +2787,9 @@ Error Box_pixi::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_pixi::dump(Indent& indent) const
+void Box_pixi::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "bits_per_channel: ";

@@ -2819,7 +2800,7 @@ std::string Box_pixi::dump(Indent& indent) const

   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -2855,15 +2836,14 @@ Error Box_pasp::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_pasp::dump(Indent& indent) const
+void Box_pasp::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "hSpacing: " << hSpacing << "\n";
   sstr << indent << "vSpacing: " << vSpacing << "\n";

-  return sstr.str();
+  return;
 }


@@ -2888,14 +2868,13 @@ Error Box_lsel::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_lsel::dump(Indent& indent) const
+void Box_lsel::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "layer_id: " << layer_id << "\n";

-  return sstr.str();
+  return;
 }


@@ -2922,15 +2901,14 @@ Error Box_clli::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_clli::dump(Indent& indent) const
+void Box_clli::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "max_content_light_level: " << clli.max_content_light_level << "\n";
   sstr << indent << "max_pic_average_light_level: " << clli.max_pic_average_light_level << "\n";

-  return sstr.str();
+  return;
 }


@@ -2973,10 +2951,9 @@ Error Box_mdcv::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_mdcv::dump(Indent& indent) const
+void Box_mdcv::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "display_primaries (x,y): ";
   sstr << "(" << mdcv.display_primaries_x[0] << ";" << mdcv.display_primaries_y[0] << "), ";
@@ -2987,7 +2964,7 @@ std::string Box_mdcv::dump(Indent& indent) const
   sstr << indent << "max display mastering luminance: " << mdcv.max_display_mastering_luminance << "\n";
   sstr << indent << "min display mastering luminance: " << mdcv.min_display_mastering_luminance << "\n";

-  return sstr.str();
+  return;
 }


@@ -3031,16 +3008,15 @@ Error Box_amve::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_amve::dump(Indent& indent) const
+void Box_amve::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "ambient_illumination: " << amve.ambient_illumination << "\n";
   sstr << indent << "ambient_light_x: " << amve.ambient_light_x << "\n";
   sstr << indent << "ambient_light_y: " << amve.ambient_light_y << "\n";

-  return sstr.str();
+  return;
 }


@@ -3072,14 +3048,13 @@ Error Box_ndwt::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ndwt::dump(Indent& indent) const
+void Box_ndwt::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "diffuse_white_luminance: " << m_diffuse_white_luminance << "\n";

-  return sstr.str();
+  return;
 }


@@ -3160,10 +3135,9 @@ template <typename T> std::ostream& operator<<(std::ostream& ostr, const std::op
 }


-std::string Box_cclv::dump(Indent& indent) const
+void Box_cclv::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "ccv_primaries_present_flag: " << m_ccv_primaries_valid << "\n";
   if (m_ccv_primaries_valid) {
@@ -3177,7 +3151,7 @@ std::string Box_cclv::dump(Indent& indent) const
   sstr << indent << "ccv_max_luminance_value: " << m_ccv_max_luminance_value << "\n";
   sstr << indent << "ccv_avg_luminance_value: " << m_ccv_avg_luminance_value << "\n";

-  return sstr.str();
+  return;
 }


@@ -3310,15 +3284,14 @@ Error Box_ispe::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ispe::dump(Indent& indent) const
+void Box_ispe::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "image width: " << m_image_width << "\n"
        << indent << "image height: " << m_image_height << "\n";

-  return sstr.str();
+  return;
 }


@@ -3500,10 +3473,9 @@ heif_property_id Box_ipma::get_property_id_for_item_ID(heif_item_id itemID, uint
 }


-std::string Box_ipma::dump(Indent& indent) const
+void Box_ipma::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const Entry& entry : m_entries) {
     sstr << indent << "associations for item ID: " << entry.item_ID << "\n";
@@ -3515,7 +3487,7 @@ std::string Box_ipma::dump(Indent& indent) const
     indent--;
   }

-  return sstr.str();
+  return;
 }


@@ -3644,10 +3616,9 @@ Error Box_auxC::write(StreamWriter& writer) const
 }


-std::string Box_auxC::dump(Indent& indent) const
+void Box_auxC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "aux type: " << m_aux_type << "\n"
        << indent << "aux subtypes: ";
@@ -3657,7 +3628,7 @@ std::string Box_auxC::dump(Indent& indent) const

   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -3686,14 +3657,13 @@ Error Box_irot::write(StreamWriter& writer) const
 }


-std::string Box_irot::dump(Indent& indent) const
+void Box_irot::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "rotation: " << m_rotation << " degrees (CCW)\n";

-  return sstr.str();
+  return;
 }


@@ -3725,10 +3695,9 @@ Error Box_imir::write(StreamWriter& writer) const
 }


-std::string Box_imir::dump(Indent& indent) const
+void Box_imir::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "mirror direction: ";
   switch (m_axis) {
@@ -3743,7 +3712,7 @@ std::string Box_imir::dump(Indent& indent) const
       break;
   }

-  return sstr.str();
+  return;
 }


@@ -3786,15 +3755,14 @@ Error Box_iscl::write(StreamWriter& writer) const
 }


-std::string Box_iscl::dump(Indent& indent) const
+void Box_iscl::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "horizontal scaling factor: " << m_target_width_numerator << " / " << m_target_width_denominator << "\n";
   sstr << indent << "vertical scaling factor:   " << m_target_height_numerator << " / " << m_target_height_denominator << "\n";

-  return sstr.str();
+  return;
 }


@@ -3856,10 +3824,9 @@ Error Box_clap::write(StreamWriter& writer) const
 }


-std::string Box_clap::dump(Indent& indent) const
+void Box_clap::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "clean_aperture: " << m_clean_aperture_width.numerator
        << "/" << m_clean_aperture_width.denominator << " x "
@@ -3870,7 +3837,7 @@ std::string Box_clap::dump(Indent& indent) const
        << m_vertical_offset.numerator << "/"
        << m_vertical_offset.denominator << "\n";

-  return sstr.str();
+  return;
 }


@@ -4196,10 +4163,9 @@ Error Box_iref::write(StreamWriter& writer) const
 }


-std::string Box_iref::dump(Indent& indent) const
+void Box_iref::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& ref : m_references) {
     sstr << indent << "reference with type '" << ref.header.get_type_string() << "'"
@@ -4211,7 +4177,7 @@ std::string Box_iref::dump(Indent& indent) const
     sstr << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -4425,10 +4391,9 @@ Error Box_rref::write(StreamWriter& writer) const
 }


-std::string Box_rref::dump(Indent& indent) const
+void Box_rref::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "reference types: ";
   for (size_t i = 0; i < m_reference_types.size(); i++) {
@@ -4437,7 +4402,7 @@ std::string Box_rref::dump(Indent& indent) const
   }
   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -4463,10 +4428,9 @@ Error Box_idat::write(StreamWriter& writer) const
 }


-std::string Box_idat::dump(Indent& indent) const
+void Box_idat::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   if (get_box_size() >= get_header_size()) {
     sstr << indent << "number of data bytes: " << get_box_size() - get_header_size() << "\n";
@@ -4474,7 +4438,7 @@ std::string Box_idat::dump(Indent& indent) const
      sstr << indent << "number of data bytes is invalid\n";
   }

-  return sstr.str();
+  return;
 }


@@ -4545,12 +4509,11 @@ Error Box_grpl::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_grpl::dump(Indent& indent) const
+void Box_grpl::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << dump_children(indent);
-  return sstr.str();
+  Box::dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);
+  return;
 }


@@ -4617,10 +4580,9 @@ void Box_EntityToGroup::write_entity_group_ids(StreamWriter& writer) const
 }


-std::string Box_EntityToGroup::dump(Indent& indent) const
+void Box_EntityToGroup::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "group id: " << group_id << "\n"
        << indent << "entity IDs: ";
@@ -4639,7 +4601,7 @@ std::string Box_EntityToGroup::dump(Indent& indent) const

   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -4660,16 +4622,15 @@ Error Box_ster::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ster::dump(Indent& indent) const
+void Box_ster::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "group id: " << group_id << "\n"
        << indent << "left image ID: " << entity_ids[0] << "\n"
        << indent << "right image ID: " << entity_ids[1] << "\n";

-  return sstr.str();
+  return;
 }


@@ -4720,10 +4681,9 @@ Error Box_pymd::write(StreamWriter& writer) const
 }


-std::string Box_pymd::dump(Indent& indent) const
+void Box_pymd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box_EntityToGroup::dump(indent);
+  Box_EntityToGroup::dump(sstr, indent, full_log);

   sstr << indent << "tile size: " << tile_size_x << "x" << tile_size_y << "\n";

@@ -4736,7 +4696,7 @@ std::string Box_pymd::dump(Indent& indent) const
     layerNr++;
   }

-  return sstr.str();
+  return;
 }


@@ -4748,13 +4708,12 @@ Error Box_dinf::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_dinf::dump(Indent& indent) const
+void Box_dinf::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << dump_children(indent);
+  Box::dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -4807,13 +4766,12 @@ Error Box_dref::write(StreamWriter& writer) const
 }


-std::string Box_dref::dump(Indent& indent) const
+void Box_dref::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << dump_children(indent);
+  Box::dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -4854,15 +4812,14 @@ Error Box_url::write(StreamWriter& writer) const
 }


-std::string Box_url::dump(Indent& indent) const
+void Box_url::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  //sstr << dump_children(indent);
+  Box::dump(sstr, indent, full_log);
+  //dump_children(sstr, indent, full_log);

   sstr << indent << "location: " << m_location << "\n";

-  return sstr.str();
+  return;
 }


@@ -4881,15 +4838,14 @@ Error Box_udes::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_udes::dump(Indent& indent) const
+void Box_udes::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "lang: " << m_lang << "\n";
   sstr << indent << "name: " << m_name << "\n";
   sstr << indent << "description: " << m_description << "\n";
   sstr << indent << "tags: " << m_tags << "\n";
-  return sstr.str();
+  return;
 }

 Error Box_udes::write(StreamWriter& writer) const
@@ -4937,10 +4893,9 @@ Box_cmin::AbsoluteIntrinsicMatrix Box_cmin::RelativeIntrinsicMatrix::to_absolute
 }


-std::string Box_cmin::dump(Indent& indent) const
+void Box_cmin::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "principal-point: " << m_matrix.principal_point_x << ", " << m_matrix.principal_point_y << "\n";
   if (m_matrix.is_anisotropic) {
     sstr << indent << "focal-length: " << m_matrix.focal_length_x << ", " << m_matrix.focal_length_y << "\n";
@@ -4951,7 +4906,7 @@ std::string Box_cmin::dump(Indent& indent) const
     sstr << indent << "no skew\n";
   }

-  return sstr.str();
+  return;
 }


@@ -5212,10 +5167,9 @@ Error Box_cmex::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_cmex::dump(Indent& indent) const
+void Box_cmex::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "camera position (um): ";
   sstr << m_matrix.pos_x << " ; ";
   sstr << m_matrix.pos_y << " ; ";
@@ -5239,7 +5193,7 @@ std::string Box_cmex::dump(Indent& indent) const

   sstr << indent << "world coordinate system id: " << m_matrix.world_coordinate_system_id << "\n";

-  return sstr.str();
+  return;
 }


@@ -5409,12 +5363,11 @@ std::string Box_taic::dump(const heif_tai_clock_info& info, Indent& indent)
 }


-std::string Box_taic::dump(Indent& indent) const {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+void Box_taic::dump(std::ostream& sstr, Indent& indent, bool full_log) const {
+  Box::dump(sstr, indent, full_log);
   sstr << dump(m_info, indent);

-  return sstr.str();
+  return;
 }

 Error Box_taic::write(StreamWriter& writer) const {
@@ -5462,14 +5415,13 @@ bool Box_taic::operator==(const Box& other) const
 }


-std::string Box_itai::dump(Indent& indent) const {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+void Box_itai::dump(std::ostream& sstr, Indent& indent, bool full_log) const {
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "tai_timestamp: " << m_timestamp.tai_timestamp << "\n";
   sstr << indent << "synchronization_state: " << int(m_timestamp.synchronization_state) << "\n";
   sstr << indent << "timestamp_generation_failure: " << int(m_timestamp.timestamp_generation_failure) << "\n";
   sstr << indent << "timestamp_is_modified: " << int(m_timestamp.timestamp_is_modified) << "\n";
-  return sstr.str();
+  return;
 }


@@ -5584,12 +5536,11 @@ Error Box_elng::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_elng::dump(Indent& indent) const
+void Box_elng::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "extended_language: " << m_lang << "\n";
-  return sstr.str();
+  return;
 }

 Error Box_elng::write(StreamWriter& writer) const
@@ -5621,12 +5572,11 @@ Error Box_gimi_content_id::write(StreamWriter& writer) const
 }


-std::string Box_gimi_content_id::dump(Indent& indent) const
+void Box_gimi_content_id::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "content ID: " << m_content_id << "\n";

-  return sstr.str();
+  return;
 }
diff --git a/libheif/box.h b/libheif/box.h
index a686fd7c..4e509956 100644
--- a/libheif/box.h
+++ b/libheif/box.h
@@ -147,7 +147,17 @@ public:

   Error parse_header(BitstreamRange& range);

-  virtual std::string dump(Indent&) const;
+  virtual void dump(std::ostream&, Indent&, bool full_log) const;
+
+  // Convenience wrapper that collects dump() into a string. By default only a
+  // bounded amount of each box is written (see MAX_DUMP_ENTRIES); pass
+  // full_log=true for the complete, potentially very large, output.
+  std::string dump_to_string(Indent& indent, bool full_log = false) const
+  {
+    std::ostringstream sstr;
+    dump(sstr, indent, full_log);
+    return sstr.str();
+  }


   virtual bool is_full_box_header() const { return false; }
@@ -206,7 +216,7 @@ public:

   void patch_file_pointers_recursively(StreamWriter&, size_t offset);

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   template<typename T> [[nodiscard]] std::shared_ptr<T> get_child_box() const
   {
@@ -300,7 +310,7 @@ protected:

   Error write_children(StreamWriter& writer) const;

-  std::string dump_children(Indent&, bool with_index = false) const;
+  void dump_children(std::ostream&, Indent&, bool full_log, bool with_index = false) const;


   // --- writing
@@ -318,7 +328,7 @@ class FullBox : public Box
 public:
   bool is_full_box_header() const override { return true; }

-  std::string dump(Indent& indent) const override;
+  void dump(std::ostream&, Indent& indent, bool full_log) const override;

   void derive_box_version() override { set_version(0); }

@@ -363,7 +373,7 @@ public:

   Error write(StreamWriter& writer) const override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

 protected:
   Error parse(BitstreamRange& range, const heif_security_limits*) override;
@@ -387,7 +397,7 @@ public:

   Error write(StreamWriter& writer) const override { return {heif_error_Usage_error, heif_suberror_Unspecified, "Cannot write dummy error box."}; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   [[nodiscard]] parse_error_fatality get_parse_error_fatality() const override;

@@ -412,7 +422,7 @@ public:
     set_short_type(fourcc("ftyp"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "File Type"; }

@@ -452,7 +462,7 @@ public:
     set_short_type(fourcc("free"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Free Space"; }

@@ -471,7 +481,7 @@ public:
     set_short_type(fourcc("meta"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Metadata"; }

@@ -488,7 +498,7 @@ public:
     set_short_type(fourcc("hdlr"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Handler Reference"; }

@@ -519,7 +529,7 @@ public:
     set_short_type(fourcc("pitm"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Primary Item"; }

@@ -548,7 +558,7 @@ public:

   void set_use_tmp_file(bool flag);

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Location"; }

@@ -649,7 +659,7 @@ public:
     set_short_type(fourcc("infe"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Info Entry"; }

@@ -711,7 +721,7 @@ public:
     set_short_type(fourcc("iinf"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Information"; }

@@ -735,7 +745,7 @@ public:
     set_short_type(fourcc("iprp"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Properties"; }

@@ -766,7 +776,7 @@ public:
                                       const std::shared_ptr<const class Box>& property,
                                       const std::shared_ptr<class Box_ipma>&) const;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Property Container"; }

@@ -793,7 +803,7 @@ public:
     m_image_height = height;
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image Spatial Extents"; }

@@ -821,7 +831,7 @@ public:
     set_short_type(fourcc("ipma"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Property Association"; }

@@ -886,7 +896,7 @@ public:

   bool is_essential() const override { return true; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image Properties for Auxiliary Images"; }

@@ -913,7 +923,7 @@ public:

   bool is_transformative_property() const override { return true; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image Rotation"; }

@@ -950,7 +960,7 @@ public:

   void set_mirror_direction(heif_transform_mirror_direction dir) { m_axis = dir; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image Mirroring"; }

@@ -991,7 +1001,7 @@ public:
     m_target_height_denominator = h_den;
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image Scaling"; }

@@ -1022,7 +1032,7 @@ public:

   bool is_transformative_property() const override { return true; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Clean Aperture"; }

@@ -1084,7 +1094,7 @@ public:
   };


-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Reference"; }

@@ -1131,7 +1141,7 @@ public:

   bool is_essential() const override { return true; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Required Reference Types"; }

@@ -1156,7 +1166,7 @@ private:
 class Box_idat : public Box
 {
 public:
-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item Data"; }

@@ -1195,7 +1205,7 @@ public:
     set_short_type(fourcc("grpl"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Groups List"; }

@@ -1207,7 +1217,7 @@ protected:
 class Box_EntityToGroup : public FullBox
 {
 public:
-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -1237,7 +1247,7 @@ public:
     set_short_type(fourcc("ster"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Stereo pair"; }

@@ -1258,7 +1268,7 @@ public:
     set_short_type(fourcc("pymd"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Image pyramid group"; }

@@ -1305,7 +1315,7 @@ public:
     set_short_type(fourcc("dinf"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Data Information"; }

@@ -1322,7 +1332,7 @@ public:
     set_short_type(fourcc("dref"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Data Reference"; }

@@ -1342,7 +1352,7 @@ public:
     set_flags(1);
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Data Entry URL"; }

@@ -1383,7 +1393,7 @@ public:
     }
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Pixel Information"; }

@@ -1410,7 +1420,7 @@ public:
   uint32_t hSpacing = 1;
   uint32_t vSpacing = 1;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Pixel Aspect Ratio"; }

@@ -1433,7 +1443,7 @@ public:

   uint16_t layer_id = 0;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Layer Selection"; }

@@ -1459,7 +1469,7 @@ public:

   heif_content_light_level clli;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Content Light Level Information"; }

@@ -1479,7 +1489,7 @@ public:

   heif_mastering_display_colour_volume mdcv;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Master Display Colour Volume"; }

@@ -1499,7 +1509,7 @@ public:

   heif_ambient_viewing_environment amve;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Ambient Viewing Environment"; }

@@ -1526,7 +1536,7 @@ public:

   void set_diffuse_white_luminance(uint32_t luminance) { m_diffuse_white_luminance = luminance; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Nominal Diffuse White"; }

@@ -1568,7 +1578,7 @@ public:
   uint32_t get_avg_luminance() const { return *m_ccv_avg_luminance_value; }
   void set_avg_luminance(uint32_t luminance) { m_ccv_avg_luminance_value = luminance; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   // TODO const char* debug_box_name() const override { return ""; }

@@ -1649,7 +1659,7 @@ public:
     }
   };

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Camera Intrinsic Matrix"; }

@@ -1706,7 +1716,7 @@ public:
     std::array<double,9> calculate_rotation_matrix() const;
   };

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Camera Extrinsic Matrix"; }

@@ -1760,7 +1770,7 @@ public:
     set_short_type(fourcc("udes"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "User Description"; }

@@ -1856,7 +1866,7 @@ public:

   static std::string dump(const heif_tai_clock_info& info, Indent&);

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "TAI Clock Information"; }

@@ -1934,7 +1944,7 @@ public:
     initialize_heif_tai_timestamp_packet(&m_timestamp);
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Item TAI Timestamp"; }

@@ -2002,7 +2012,7 @@ public:

   bool is_transformative_property() const override { return false; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "GIMI Content ID"; }

@@ -2041,7 +2051,7 @@ public:
     set_short_type(fourcc("elng"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Extended language"; }

diff --git a/libheif/codecs/avc_boxes.cc b/libheif/codecs/avc_boxes.cc
index 00654964..89bd4562 100644
--- a/libheif/codecs/avc_boxes.cc
+++ b/libheif/codecs/avc_boxes.cc
@@ -166,10 +166,9 @@ Error Box_avcC::write(StreamWriter& writer) const
   return Error::Ok;
 }

-std::string Box_avcC::dump(Indent& indent) const
+void Box_avcC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "configuration_version: " << ((int) m_configuration.configuration_version) << "\n"
       << indent << "AVCProfileIndication: " << ((int) m_configuration.AVCProfileIndication) << " (" << profileIndicationAsText() << ")\n"
       << indent << "profile_compatibility: " << ((int) m_configuration.profile_compatibility) << "\n"
@@ -224,7 +223,7 @@ std::string Box_avcC::dump(Indent& indent) const
     sstr << std::dec;
   }

-  return sstr.str();
+  return;
 }

 std::string Box_avcC::profileIndicationAsText() const
diff --git a/libheif/codecs/avc_boxes.h b/libheif/codecs/avc_boxes.h
index 6d043604..dc1c3d30 100644
--- a/libheif/codecs/avc_boxes.h
+++ b/libheif/codecs/avc_boxes.h
@@ -86,7 +86,7 @@ public:

   void append_pps_nal(const uint8_t* data, size_t size);

-  std::string dump(Indent &) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter &writer) const override;

diff --git a/libheif/codecs/avif_boxes.cc b/libheif/codecs/avif_boxes.cc
index bf6525ba..859b0957 100644
--- a/libheif/codecs/avif_boxes.cc
+++ b/libheif/codecs/avif_boxes.cc
@@ -113,10 +113,9 @@ Error Box_av1C::write(StreamWriter& writer) const
 }


-std::string Box_av1C::dump(Indent& indent) const
+void Box_av1C::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   const auto& c = m_configuration; // abbreviation

@@ -145,7 +144,7 @@ std::string Box_av1C::dump(Indent& indent) const
   }
   sstr << std::dec << "\n";

-  return sstr.str();
+  return;
 }


@@ -199,14 +198,13 @@ Error Box_a1op::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_a1op::dump(Indent& indent) const
+void Box_a1op::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "op-index: " << ((int) op_index) << "\n";

-  return sstr.str();
+  return;
 }


@@ -239,14 +237,13 @@ Error Box_a1lx::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_a1lx::dump(Indent& indent) const
+void Box_a1lx::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "layer-sizes: [" << layer_size[0] << "," << layer_size[1] << "," << layer_size[2] << "]\n";

-  return sstr.str();
+  return;
 }


diff --git a/libheif/codecs/avif_boxes.h b/libheif/codecs/avif_boxes.h
index a25b7a86..f59f51d4 100644
--- a/libheif/codecs/avif_boxes.h
+++ b/libheif/codecs/avif_boxes.h
@@ -88,7 +88,7 @@ public:
   };


-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   bool get_headers(std::vector<uint8_t>* dest) const
   {
@@ -134,7 +134,7 @@ public:

   uint8_t op_index = 0;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -153,7 +153,7 @@ public:

   uint32_t layer_size[3]{};

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

diff --git a/libheif/codecs/hevc_boxes.cc b/libheif/codecs/hevc_boxes.cc
index d963758e..c18e36d8 100644
--- a/libheif/codecs/hevc_boxes.cc
+++ b/libheif/codecs/hevc_boxes.cc
@@ -272,10 +272,9 @@ Error Box_hvcC::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_hvcC::dump(Indent& indent) const
+void Box_hvcC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   const auto& c = m_configuration; // abbreviation

@@ -356,7 +355,7 @@ std::string Box_hvcC::dump(Indent& indent) const
     indent--;
   }

-  return sstr.str();
+  return;
 }


diff --git a/libheif/codecs/hevc_boxes.h b/libheif/codecs/hevc_boxes.h
index e589ced2..a7c6de5b 100644
--- a/libheif/codecs/hevc_boxes.h
+++ b/libheif/codecs/hevc_boxes.h
@@ -105,7 +105,7 @@ public:
   bool is_essential() const override { return true; }


-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "HEVC Configuration Item"; }

diff --git a/libheif/codecs/jpeg2000_boxes.cc b/libheif/codecs/jpeg2000_boxes.cc
index ba7458e5..a25b2329 100644
--- a/libheif/codecs/jpeg2000_boxes.cc
+++ b/libheif/codecs/jpeg2000_boxes.cc
@@ -64,10 +64,9 @@ Error Box_cdef::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_cdef::dump(Indent& indent) const
+void Box_cdef::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& channel : m_channels) {
     sstr << indent << "channel_index: " << channel.channel_index
@@ -75,7 +74,7 @@ std::string Box_cdef::dump(Indent& indent) const
          << ", channel_association: " << channel.channel_association << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -146,10 +145,9 @@ Error Box_cmap::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_cmap::dump(Indent& indent) const
+void Box_cmap::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& component : m_components) {
     sstr << indent << "component_index: " << component.component_index
@@ -157,7 +155,7 @@ std::string Box_cmap::dump(Indent& indent) const
          << ", palette_colour: " << (int) (component.palette_colour) << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -257,10 +255,9 @@ Error Box_pclr::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_pclr::dump(Indent& indent) const
+void Box_pclr::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "NE: " << m_entries.size();
   sstr << ", NPC: " << (int) get_num_columns();
@@ -271,7 +268,7 @@ std::string Box_pclr::dump(Indent& indent) const
   // TODO: maybe dump entries too?
   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -344,10 +341,9 @@ Error Box_j2kL::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_j2kL::dump(Indent& indent) const
+void Box_j2kL::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& layer : m_layers) {
     sstr << indent << "layer_id: " << layer.layer_id
@@ -355,7 +351,7 @@ std::string Box_j2kL::dump(Indent& indent) const
          << ", decode_layers: " << layer.decode_layers << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -381,14 +377,13 @@ Error Box_j2kH::parse(BitstreamRange& range, const heif_security_limits* limits)
   return read_children(range, READ_CHILDREN_ALL, limits);
 }

-std::string Box_j2kH::dump(Indent& indent) const
+void Box_j2kH::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

-  sstr << dump_children(indent);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


diff --git a/libheif/codecs/jpeg2000_boxes.h b/libheif/codecs/jpeg2000_boxes.h
index fd165ae9..9530f31c 100644
--- a/libheif/codecs/jpeg2000_boxes.h
+++ b/libheif/codecs/jpeg2000_boxes.h
@@ -57,7 +57,7 @@ class Box_cdef : public Box {
 public:
     Box_cdef() { set_short_type(fourcc("cdef")); }

-    std::string dump(Indent &) const override;
+    void dump(std::ostream&, Indent&, bool full_log) const override;

     Error write(StreamWriter &writer) const override;

@@ -141,7 +141,7 @@ class Box_cmap : public Box
 public:
     Box_cmap() { set_short_type(fourcc("cmap")); }

-    std::string dump(Indent &) const override;
+    void dump(std::ostream&, Indent&, bool full_log) const override;

     Error write(StreamWriter &writer) const override;

@@ -188,7 +188,7 @@ public:
         set_short_type(fourcc("pclr"));
     }

-    std::string dump(Indent &) const override;
+    void dump(std::ostream&, Indent&, bool full_log) const override;

     Error write(StreamWriter &writer) const override;

@@ -274,7 +274,7 @@ class Box_j2kL : public FullBox
 public:
     Box_j2kL() { set_short_type(fourcc("j2kL")); }

-    std::string dump(Indent &) const override;
+    void dump(std::ostream&, Indent&, bool full_log) const override;

     Error write(StreamWriter &writer) const override;

@@ -321,7 +321,7 @@ public:

     bool is_essential() const override { return true; }

-    std::string dump(Indent &) const override;
+    void dump(std::ostream&, Indent&, bool full_log) const override;

     // Default write behaviour for a container is to write children

diff --git a/libheif/codecs/jpeg_boxes.cc b/libheif/codecs/jpeg_boxes.cc
index c718b9ea..d6d9ad7e 100644
--- a/libheif/codecs/jpeg_boxes.cc
+++ b/libheif/codecs/jpeg_boxes.cc
@@ -38,14 +38,13 @@ size_t find_jpeg_marker_start(const std::vector<uint8_t>& data, uint8_t marker_t
 }


-std::string Box_jpgC::dump(Indent& indent) const
+void Box_jpgC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "num bytes: " << m_data.size() << "\n";

-  return sstr.str();
+  return;
 }


diff --git a/libheif/codecs/jpeg_boxes.h b/libheif/codecs/jpeg_boxes.h
index 2e70427d..73476a2a 100644
--- a/libheif/codecs/jpeg_boxes.h
+++ b/libheif/codecs/jpeg_boxes.h
@@ -41,7 +41,7 @@ public:

   void set_data(const std::vector<uint8_t>& data) { m_data = data; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

diff --git a/libheif/codecs/uncompressed/unc_boxes.cc b/libheif/codecs/uncompressed/unc_boxes.cc
index 3d435c66..4c233fc7 100644
--- a/libheif/codecs/uncompressed/unc_boxes.cc
+++ b/libheif/codecs/uncompressed/unc_boxes.cc
@@ -203,10 +203,9 @@ bool Box_cmpd::has_component(heif_cmpd_component_type type) const
 }


-std::string Box_cmpd::dump(Indent& indent) const
+void Box_cmpd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& component : m_components) {
     sstr << indent << "component_type: " << component.get_component_type_name();
@@ -216,7 +215,7 @@ std::string Box_cmpd::dump(Indent& indent) const
     }
   }

-  return sstr.str();
+  return;
 }

 Error Box_cmpd::write(StreamWriter& writer) const
@@ -374,10 +373,9 @@ Error Box_uncC::parse(BitstreamRange& range, const heif_security_limits* limits)



-std::string Box_uncC::dump(Indent& indent) const
+void Box_uncC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   sstr << indent << "profile: " << m_profile;
   if (m_profile != 0) {
@@ -416,7 +414,7 @@ std::string Box_uncC::dump(Indent& indent) const

     sstr << indent << "num_tile_rows: " << m_num_tile_rows << "\n";
   }
-  return sstr.str();
+  return;
 }


@@ -769,13 +767,12 @@ Error Box_cmpC::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_cmpC::dump(Indent& indent) const
+void Box_cmpC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "compression_type: " << fourcc_to_string(m_compression_type) << "\n";
   sstr << indent << "compressed_entity_type: " << (int)m_compressed_unit_type << "\n";
-  return sstr.str();
+  return;
 }

 Error Box_cmpC::write(StreamWriter& writer) const
@@ -885,15 +882,14 @@ Error Box_icef::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_icef::dump(Indent& indent) const
+void Box_icef::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "num_compressed_units: " << m_unit_infos.size() << "\n";
   for (CompressedUnitInfo unit_info: m_unit_infos) {
     sstr << indent << "unit_offset: " << unit_info.unit_offset << ", unit_size: " << unit_info.unit_size << "\n";
   }
-  return sstr.str();
+  return;
 }

 Error Box_icef::write(StreamWriter& writer) const
@@ -1048,18 +1044,17 @@ Error Box_cpat::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_cpat::dump(Indent& indent) const
+void Box_cpat::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "pattern_width: " << get_pattern_width() << "\n";
   sstr << indent << "pattern_height: " << get_pattern_height() << "\n";

   for (const auto& pixel : m_pattern.pixels) {
     sstr << indent << "component index: " << pixel.cmpd_index << ", gain: " << pixel.component_gain << "\n";
   }
-  return sstr.str();
+  return;
 }


@@ -1134,11 +1129,10 @@ Error Box_splz::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_splz::dump(Indent& indent) const
+void Box_splz::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "component_count: " << m_pattern.component_ids.size() << "\n";
   for (size_t i = 0; i < m_pattern.component_ids.size(); i++) {
@@ -1160,7 +1154,7 @@ std::string Box_splz::dump(Indent& indent) const
     }
   }

-  return sstr.str();
+  return;
 }


@@ -1248,11 +1242,10 @@ Error Box_sbpm::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_sbpm::dump(Indent& indent) const
+void Box_sbpm::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "component_count: " << m_map.component_ids.size() << "\n";
   for (size_t i = 0; i < m_map.component_ids.size(); i++) {
@@ -1277,7 +1270,7 @@ std::string Box_sbpm::dump(Indent& indent) const
          << ", column=" << m_map.bad_pixels[i].column << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -1376,11 +1369,10 @@ Error Box_snuc::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_snuc::dump(Indent& indent) const
+void Box_snuc::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "component_count: " << m_nuc.component_ids.size() << "\n";
   for (size_t i = 0; i < m_nuc.component_ids.size(); i++) {
@@ -1395,7 +1387,7 @@ std::string Box_snuc::dump(Indent& indent) const
   sstr << indent << "nuc_gains: " << num_pixels << " values\n";
   sstr << indent << "nuc_offsets: " << num_pixels << " values\n";

-  return sstr.str();
+  return;
 }


@@ -1448,11 +1440,10 @@ Error Box_cloc::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_cloc::dump(Indent& indent) const
+void Box_cloc::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   static const char* location_names[] = {
     "h=0,   v=0.5",   // 0
@@ -1470,7 +1461,7 @@ std::string Box_cloc::dump(Indent& indent) const
   }
   sstr << "\n";

-  return sstr.str();
+  return;
 }


@@ -1528,14 +1519,13 @@ Error Box_gimi_component_content_ids::write(StreamWriter& writer) const
 }


-std::string Box_gimi_component_content_ids::dump(Indent& indent) const
+void Box_gimi_component_content_ids::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (size_t i = 0; i < m_content_ids.size(); i++) {
     sstr << indent << "[" << i << "] content ID: " << m_content_ids[i] << "\n";
   }

-  return sstr.str();
+  return;
 }
diff --git a/libheif/codecs/uncompressed/unc_boxes.h b/libheif/codecs/uncompressed/unc_boxes.h
index c29910bc..025078c4 100644
--- a/libheif/codecs/uncompressed/unc_boxes.h
+++ b/libheif/codecs/uncompressed/unc_boxes.h
@@ -46,7 +46,7 @@ public:
     set_short_type(fourcc("cmpd"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -103,7 +103,7 @@ public:
     set_version(is_minimized() ? 1 : 0);
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -271,7 +271,7 @@ public:
     set_short_type(fourcc("cmpC"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   uint32_t get_compression_type() const { return m_compression_type; }

@@ -327,7 +327,7 @@ public:
     m_unit_infos[tile_idx] = unit_info;
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -368,7 +368,7 @@ public:

   void set_pattern(const BayerPatternCmpd& pattern) { m_pattern = pattern; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -397,7 +397,7 @@ public:

   void set_pattern(const PolarizationPattern& pattern) { m_pattern = pattern; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -425,7 +425,7 @@ public:
   const SensorBadPixelsMap& get_bad_pixels_map() const { return m_map; }
   void set_bad_pixels_map(const SensorBadPixelsMap& map) { m_map = map; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;
   Error write(StreamWriter& writer) const override;

 protected:
@@ -451,7 +451,7 @@ public:
   const SensorNonUniformityCorrection& get_nuc() const { return m_nuc; }
   void set_nuc(const SensorNonUniformityCorrection& nuc) { m_nuc = nuc; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;
   Error write(StreamWriter& writer) const override;

 protected:
@@ -477,7 +477,7 @@ public:
   uint8_t get_chroma_location() const { return m_chroma_location; }
   void set_chroma_location(uint8_t loc) { m_chroma_location = loc; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;
   Error write(StreamWriter& writer) const override;

 protected:
@@ -522,7 +522,7 @@ public:

   bool is_transformative_property() const override { return false; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "GIMI Component Content IDs"; }

diff --git a/libheif/codecs/vvc_boxes.cc b/libheif/codecs/vvc_boxes.cc
index 5c042c20..bff5adb7 100644
--- a/libheif/codecs/vvc_boxes.cc
+++ b/libheif/codecs/vvc_boxes.cc
@@ -368,10 +368,9 @@ const char* NAL_name(uint8_t nal_type)
 }


-std::string Box_vvcC::dump(Indent& indent) const
+void Box_vvcC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   const auto& c = m_configuration; // abbreviation

@@ -411,7 +410,7 @@ std::string Box_vvcC::dump(Indent& indent) const
     indent--;
   }

-  return sstr.str();
+  return;
 }


diff --git a/libheif/codecs/vvc_boxes.h b/libheif/codecs/vvc_boxes.h
index 5dd7f689..e1c31c52 100644
--- a/libheif/codecs/vvc_boxes.h
+++ b/libheif/codecs/vvc_boxes.h
@@ -72,7 +72,7 @@ public:
   };


-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   bool get_headers(std::vector<uint8_t>* dest) const;

diff --git a/libheif/file.cc b/libheif/file.cc
index 725aef20..4db68295 100644
--- a/libheif/file.cc
+++ b/libheif/file.cc
@@ -353,7 +353,8 @@ std::string HeifFile::debug_dump_boxes() const
     }

     Indent indent;
-    sstr << box->dump(indent);
+    box->dump(sstr, indent, false);
+    reset_stream_format(sstr);
   }

   return sstr.str();
diff --git a/libheif/image-items/mask_image.cc b/libheif/image-items/mask_image.cc
index 532bfdea..907813fd 100644
--- a/libheif/image-items/mask_image.cc
+++ b/libheif/image-items/mask_image.cc
@@ -40,12 +40,11 @@ Error Box_mskC::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_mskC::dump(Indent& indent) const
+void Box_mskC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "bits_per_pixel: " << ((int)m_bits_per_pixel) << "\n";
-  return sstr.str();
+  return;
 }

 Error Box_mskC::write(StreamWriter& writer) const
diff --git a/libheif/image-items/mask_image.h b/libheif/image-items/mask_image.h
index 33e97c97..9f420b57 100644
--- a/libheif/image-items/mask_image.h
+++ b/libheif/image-items/mask_image.h
@@ -53,7 +53,7 @@ public:

   bool is_essential() const override { return true; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

diff --git a/libheif/image-items/tiled.cc b/libheif/image-items/tiled.cc
index 3e4e8a40..b8a8f5e6 100644
--- a/libheif/image-items/tiled.cc
+++ b/libheif/image-items/tiled.cc
@@ -218,11 +218,10 @@ Error Box_tilC::write(StreamWriter& writer) const
 }


-std::string Box_tilC::dump(Indent& indent) const
+void Box_tilC::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;

-  sstr << BoxHeader::dump(indent);
+  BoxHeader::dump(sstr, indent, full_log);

   sstr << indent << "version: " << ((int) get_version()) << "\n"
        //<< indent << "image size: " << m_parameters.image_width << "x" << m_parameters.image_height << "\n"
@@ -233,11 +232,8 @@ std::string Box_tilC::dump(Indent& indent) const
        << indent << "size field length: " << ((int) m_parameters.size_field_length) << " bits\n"
        << indent << "number of extra dimensions: " << ((int) m_parameters.number_of_extra_dimensions) << "\n";

-  sstr << indent << "tile properties:\n"
-       << dump_children(indent, true);
-
-  return sstr.str();
-
+  sstr << indent << "tile properties:\n";
+  dump_children(sstr, indent, full_log, true);
 }


diff --git a/libheif/image-items/tiled.h b/libheif/image-items/tiled.h
index 561aad9c..cc1dfdb7 100644
--- a/libheif/image-items/tiled.h
+++ b/libheif/image-items/tiled.h
@@ -69,7 +69,7 @@ public:

   Error write(StreamWriter& writer) const override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   std::vector<std::shared_ptr<Box>>& get_tile_properties() { return m_children; }

diff --git a/libheif/logging.h b/libheif/logging.h
index 555fe620..0a765d11 100644
--- a/libheif/logging.h
+++ b/libheif/logging.h
@@ -29,6 +29,7 @@
 #include <memory>
 #include <limits>
 #include <istream>
+#include <ostream>


 class Indent
@@ -59,6 +60,18 @@ inline std::ostream& operator<<(std::ostream& ostr, const Indent& indent)
   return ostr;
 }

+
+// dump() writes every box into one shared stream, so a sticky modifier such as
+// std::hex or std::setfill left behind by one box would leak into the next.
+// Reset the stream to its defaults (decimal, blank fill) between boxes so each
+// one starts formatting from a known state.
+inline void reset_stream_format(std::ostream& ostr)
+{
+  ostr << std::dec << std::noboolalpha;
+  ostr.fill(' ');
+}
+
+
 std::string write_raw_data_as_hex(const uint8_t* data, size_t len,
                                   const std::string& firstLineIndent,
                                   const std::string& remainingLinesIndent);
diff --git a/libheif/mini.cc b/libheif/mini.cc
index 35b85b68..6cfb1573 100644
--- a/libheif/mini.cc
+++ b/libheif/mini.cc
@@ -561,10 +561,9 @@ Error Box_mini::parse(BitstreamRange &range, const heif_security_limits *limits)
   return range.get_error();
 }

-std::string Box_mini::dump(Indent &indent) const
+void Box_mini::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "version: " << (int)m_version << "\n";

   sstr << indent << "explicit_codec_types_flag: " << m_explicit_codec_types_flag << "\n";
@@ -845,7 +844,7 @@ std::string Box_mini::dump(Indent &indent) const
   {
     sstr << "xmp_data offset: " << m_xmp_item_data_offset << ", size: " << m_xmp_data_size << "\n";
   }
-  return sstr.str();
+  return;
 }


diff --git a/libheif/mini.h b/libheif/mini.h
index 339a2328..59feaef9 100644
--- a/libheif/mini.h
+++ b/libheif/mini.h
@@ -140,7 +140,7 @@ public:
   void set_tmap_amve(std::shared_ptr<Box_amve> box) { m_tmap_amve = std::move(box); }
   void set_tmap_ndwt(std::shared_ptr<Box_ndwt> box) { m_tmap_ndwt = std::move(box); }

-  std::string dump(Indent &) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

diff --git a/libheif/nclx.cc b/libheif/nclx.cc
index f048c5b9..796d3152 100644
--- a/libheif/nclx.cc
+++ b/libheif/nclx.cc
@@ -438,40 +438,37 @@ Error Box_colr::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_colr::dump(Indent& indent) const
+void Box_colr::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   if (m_color_profile) {
     sstr << indent << "colour_type: " << fourcc_to_string(get_color_profile_type()) << "\n";
-    sstr << m_color_profile->dump(indent);
+    m_color_profile->dump(sstr, indent, full_log);
   }
   else {
     sstr << indent << "colour_type: ---\n";
     sstr << "no color profile\n";
   }

-  return sstr.str();
+  return;
 }


-std::string color_profile_raw::dump(Indent& indent) const
+void color_profile_raw::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
   sstr << indent << "profile size: " << m_data.size() << "\n";
-  return sstr.str();
+  return;
 }


-std::string color_profile_nclx::dump(Indent& indent) const
+void color_profile_nclx::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
   sstr << indent << "colour_primaries: " << m_profile.m_colour_primaries << "\n"
        << indent << "transfer_characteristics: " << m_profile.m_transfer_characteristics << "\n"
        << indent << "matrix_coefficients: " << m_profile.m_matrix_coefficients << "\n"
        << indent << "full_range_flag: " << m_profile.m_full_range_flag << "\n";
-  return sstr.str();
+  return;
 }


diff --git a/libheif/nclx.h b/libheif/nclx.h
index 1192cd79..1eac63b8 100644
--- a/libheif/nclx.h
+++ b/libheif/nclx.h
@@ -93,7 +93,7 @@ public:

   virtual uint32_t get_type() const = 0;

-  virtual std::string dump(Indent&) const = 0;
+  virtual void dump(std::ostream&, Indent&, bool full_log) const = 0;

   virtual Error write(StreamWriter& writer) const = 0;
 };
@@ -108,7 +108,7 @@ public:

   const std::vector<uint8_t>& get_data() const { return m_data; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error write(StreamWriter& writer) const override;

@@ -183,7 +183,7 @@ public:

   uint32_t get_type() const override { return fourcc("nclx"); }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   Error parse(BitstreamRange& range);

@@ -206,7 +206,7 @@ public:
     set_short_type(fourcc("colr"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   uint32_t get_color_profile_type() const { return m_color_profile->get_type(); }

diff --git a/libheif/omaf_boxes.cc b/libheif/omaf_boxes.cc
index 2297d45c..32d29daa 100644
--- a/libheif/omaf_boxes.cc
+++ b/libheif/omaf_boxes.cc
@@ -38,10 +38,9 @@ Error Box_prfr::parse(BitstreamRange& range, const heif_security_limits* limits)
   return range.get_error();
 }

-std::string Box_prfr::dump(Indent& indent) const
+void Box_prfr::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "projection_type: ";
   switch (m_projection) {
     case heif_omaf_image_projection_equirectangular:
@@ -54,7 +53,7 @@ std::string Box_prfr::dump(Indent& indent) const
       sstr << "unknown (" << m_projection << ")\n";
       break;
   }
-  return sstr.str();
+  return;
 }

 Error Box_prfr::write(StreamWriter& writer) const
diff --git a/libheif/omaf_boxes.h b/libheif/omaf_boxes.h
index 11dfafac..cbdc12eb 100644
--- a/libheif/omaf_boxes.h
+++ b/libheif/omaf_boxes.h
@@ -42,7 +42,7 @@ public:

   Error set_image_projection(heif_omaf_image_projection projection);

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Projection Format"; }

diff --git a/libheif/sequences/seq_boxes.cc b/libheif/sequences/seq_boxes.cc
index 565ea8cb..edbb2995 100644
--- a/libheif/sequences/seq_boxes.cc
+++ b/libheif/sequences/seq_boxes.cc
@@ -32,13 +32,12 @@ Error Box_container::parse(BitstreamRange& range, const heif_security_limits* li
 }


-std::string Box_container::dump(Indent& indent) const
+void Box_container::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << dump_children(indent);
+  Box::dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -91,10 +90,9 @@ Error Box_mvhd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_mvhd::dump(Indent& indent) const
+void Box_mvhd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "creation time:     " << m_creation_time << "\n"
       << indent << "modification time: " << m_modification_time << "\n"
       << indent << "timescale: " << m_timescale << "\n"
@@ -111,7 +109,7 @@ std::string Box_mvhd::dump(Indent& indent) const
   }
   sstr << indent << "next_track_ID: " << m_next_track_ID << "\n";

-  return sstr.str();
+  return;
 }


@@ -216,10 +214,9 @@ Error Box_tkhd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_tkhd::dump(Indent& indent) const
+void Box_tkhd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "track enabled: " << ((get_flags() & Track_enabled) ? "yes" : "no") << "\n"
        << indent << "track in movie: " << ((get_flags() & Track_in_movie) ? "yes" : "no") << "\n"
        << indent << "track in preview: " << ((get_flags() & Track_in_preview) ? "yes" : "no") << "\n"
@@ -243,7 +240,7 @@ std::string Box_tkhd::dump(Indent& indent) const
   sstr << indent << "width: " << get_width() << "\n"
       << indent << "height: " << get_height() << "\n";

-  return sstr.str();
+  return;
 }


@@ -332,17 +329,16 @@ Error Box_mdhd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_mdhd::dump(Indent& indent) const
+void Box_mdhd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "creation time:     " << m_creation_time << "\n"
       << indent << "modification time: " << m_modification_time << "\n"
       << indent << "timescale: " << m_timescale << "\n"
       << indent << "duration: " << m_duration << "\n";
   sstr << indent << "language: " << m_language << "\n";

-  return sstr.str();
+  return;
 }


@@ -407,10 +403,9 @@ Error Box_vmhd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_vmhd::dump(Indent& indent) const
+void Box_vmhd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "graphics mode: " << m_graphics_mode;
   if (m_graphics_mode == 0) {
     sstr << " (copy)";
@@ -418,7 +413,7 @@ std::string Box_vmhd::dump(Indent& indent) const
   sstr << "\n"
        << indent << "op color: " << m_op_color[0] << "; " << m_op_color[1] << "; " << m_op_color[2] << "\n";

-  return sstr.str();
+  return;
 }


@@ -449,12 +444,11 @@ Error Box_nmhd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_nmhd::dump(Indent& indent) const
+void Box_nmhd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

-  return sstr.str();
+  return;
 }


@@ -513,18 +507,17 @@ Error Box_stsd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stsd::dump(Indent& indent) const
+void Box_stsd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_sample_entries.size(); i++) {
     sstr << indent << "[" << i << "]\n";
     indent++;
-    sstr << m_sample_entries[i]->dump(indent);
+    m_sample_entries[i]->dump(sstr, indent, full_log);
     indent--;
   }

-  return sstr.str();
+  return;
 }


@@ -625,15 +618,14 @@ Error Box_stts::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stts::dump(Indent& indent) const
+void Box_stts::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_entries.size(); i++) {
     sstr << indent << "[" << i << "] : cnt=" << m_entries[i].sample_count << ", delta=" << m_entries[i].sample_delta << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -819,15 +811,14 @@ Error Box_ctts::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ctts::dump(Indent& indent) const
+void Box_ctts::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_entries.size(); i++) {
     sstr << indent << "[" << i << "] : cnt=" << m_entries[i].sample_count << ", offset=" << m_entries[i].sample_offset << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -989,10 +980,9 @@ Error Box_stsc::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stsc::dump(Indent& indent) const
+void Box_stsc::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_entries.size(); i++) {
     sstr << indent << "[" << i << "]\n"
         << indent << "  first chunk: " << m_entries[i].first_chunk << "\n"
@@ -1000,7 +990,7 @@ std::string Box_stsc::dump(Indent& indent) const
         << indent << "  sample description index: " << m_entries[i].sample_description_index << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -1091,15 +1081,14 @@ Error Box_stco::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stco::dump(Indent& indent) const
+void Box_stco::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_offsets.size(); i++) {
     sstr << indent << "[" << i << "] : 0x" << std::hex << m_offsets[i] << std::dec << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -1193,10 +1182,9 @@ Error Box_stsz::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stsz::dump(Indent& indent) const
+void Box_stsz::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "sample count: " << m_sample_count << "\n";
   if (m_fixed_sample_size == 0) {
     for (size_t i = 0; i < m_sample_sizes.size(); i++) {
@@ -1207,7 +1195,7 @@ std::string Box_stsz::dump(Indent& indent) const
     sstr << indent << "fixed sample size: " << m_fixed_sample_size << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -1288,15 +1276,14 @@ Error Box_stss::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_stss::dump(Indent& indent) const
+void Box_stss::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   for (size_t i = 0; i < m_sync_samples.size(); i++) {
     sstr << indent << "[" << i << "] : " << m_sync_samples[i] << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -1382,9 +1369,8 @@ Error VisualSampleEntry::write(StreamWriter& writer) const
 }


-std::string VisualSampleEntry::dump(Indent& indent) const
+void VisualSampleEntry::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
   sstr << indent << "data reference index: " << data_reference_index << "\n"
        << indent << "width: " << width << "\n"
        << indent << "height: " << height << "\n"
@@ -1394,7 +1380,7 @@ std::string VisualSampleEntry::dump(Indent& indent) const
        << indent << "compressorname: " << compressorname << "\n"
        << indent << "depth: " << depth << "\n";

-  return sstr.str();
+  return;
 }


@@ -1414,13 +1400,12 @@ Error Box_URIMetaSampleEntry::write(StreamWriter& writer) const
 }


-std::string Box_URIMetaSampleEntry::dump(Indent& indent) const
+void Box_URIMetaSampleEntry::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);
   sstr << indent << "data reference index: " << data_reference_index << "\n";
-  sstr << dump_children(indent);
-  return sstr.str();
+  dump_children(sstr, indent, full_log);
+  return;
 }


@@ -1452,13 +1437,12 @@ Error Box_uri::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_uri::dump(Indent& indent) const
+void Box_uri::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "uri: " << m_uri << "\n";

-  return sstr.str();
+  return;
 }


@@ -1495,17 +1479,16 @@ Error Box_ccst::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_ccst::dump(Indent& indent) const
+void Box_ccst::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
   const auto& constraints = m_codingConstraints;

-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "all ref pics intra: " << std::boolalpha <<constraints.all_ref_pics_intra << "\n"
        << indent << "intra pred used: " << constraints.intra_pred_used << "\n"
        << indent << "max ref per pic: " << ((int) constraints.max_ref_per_pic) << "\n";

-  return sstr.str();
+  return;
 }


@@ -1549,13 +1532,12 @@ Error Box_auxi::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_auxi::dump(Indent& indent) const
+void Box_auxi::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "aux track info type: " << m_aux_track_type << "\n";

-  return sstr.str();
+  return;
 }


@@ -1588,13 +1570,12 @@ Error Box_VisualSampleEntry::write(StreamWriter& writer) const
 }


-std::string Box_VisualSampleEntry::dump(Indent& indent) const
+void Box_VisualSampleEntry::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << Box::dump(indent);
-  sstr << m_visualSampleEntry.dump(indent);
-  sstr << dump_children(indent);
-  return sstr.str();
+  Box::dump(sstr, indent, full_log);
+  m_visualSampleEntry.dump(sstr, indent, full_log);
+  dump_children(sstr, indent, full_log);
+  return;
 }


@@ -1614,10 +1595,9 @@ Error Box_VisualSampleEntry::parse(BitstreamRange& range, const heif_security_li
 }


-std::string Box_sbgp::dump(Indent& indent) const
+void Box_sbgp::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);
   sstr << indent << "grouping_type: " << fourcc_to_string(m_grouping_type) << "\n";

   if (m_grouping_type_parameter) {
@@ -1631,7 +1611,7 @@ std::string Box_sbgp::dump(Indent& indent) const
   }
   sstr << indent << "total samples: " << total_samples << "\n";

-  return sstr.str();
+  return;
 }


@@ -1757,10 +1737,9 @@ void Box_sgpd::derive_box_version()
 }


-std::string Box_sgpd::dump(Indent& indent) const
+void Box_sgpd::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "grouping_type: " << fourcc_to_string(m_grouping_type) << "\n";
   if (m_default_length) {
@@ -1780,7 +1759,7 @@ std::string Box_sgpd::dump(Indent& indent) const
     }
   }

-  return sstr.str();
+  return;
 }


@@ -1863,16 +1842,15 @@ Error Box_sgpd::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_btrt::dump(Indent& indent) const
+void Box_btrt::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "bufferSizeDB: " << m_bufferSizeDB << " bytes\n";
   sstr << indent << "max bitrate: " << m_maxBitrate << " bits/sec\n";
   sstr << indent << "avg bitrate: " << m_avgBitrate << " bits/sec\n";

-  return sstr.str();
+  return;
 }


@@ -1961,10 +1939,9 @@ uint8_t Box_saiz::get_sample_size(uint32_t idx)
 }


-std::string Box_saiz::dump(Indent& indent) const
+void Box_saiz::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "aux_info_type: ";
   if (m_aux_info_type == 0) {
@@ -1996,7 +1973,7 @@ std::string Box_saiz::dump(Indent& indent) const
     }
   }

-  return sstr.str();
+  return;
 }


@@ -2106,10 +2083,9 @@ uint64_t Box_saio::get_chunk_offset(uint32_t idx) const
 }


-std::string Box_saio::dump(Indent& indent) const
+void Box_saio::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "aux_info_type: ";
   if (m_aux_info_type == 0) {
@@ -2131,7 +2107,7 @@ std::string Box_saio::dump(Indent& indent) const
     sstr << indent << "[" << i << "] : 0x" << std::hex << m_chunk_offset[i] << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -2235,14 +2211,14 @@ Error Box_saio::parse(BitstreamRange& range, const heif_security_limits* limits)
 }


-std::string Box_sdtp::dump(Indent& indent) const
+void Box_sdtp::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::stringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   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;
@@ -2259,7 +2235,7 @@ std::string Box_sdtp::dump(Indent& indent) const
         << indent << spaces << "has_redundancy=" << (int) get_has_redundancy(i) << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -2361,10 +2337,9 @@ Error Box_tref::write(StreamWriter& writer) const
 }


-std::string Box_tref::dump(Indent& indent) const
+void Box_tref::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << Box::dump(indent);
+  Box::dump(sstr, indent, full_log);

   for (const auto& ref : m_references) {
     sstr << indent << "reference with type '" << fourcc_to_string(ref.reference_type) << "'"
@@ -2375,7 +2350,7 @@ std::string Box_tref::dump(Indent& indent) const
     sstr << "\n";
   }

-  return sstr.str();
+  return;
 }


@@ -2512,10 +2487,9 @@ Error Box_elst::write(StreamWriter& writer) const
 }


-std::string Box_elst::dump(Indent& indent) const
+void Box_elst::dump(std::ostream& sstr, Indent& indent, bool full_log) const
 {
-  std::ostringstream sstr;
-  sstr << FullBox::dump(indent);
+  FullBox::dump(sstr, indent, full_log);

   sstr << indent << "repeat list: " << ((get_flags() & Flags::Repeat_EditList) ? "yes" : "no") << "\n";

@@ -2526,7 +2500,7 @@ std::string Box_elst::dump(Indent& indent) const
     sstr << indent << "media rate fraction: " << entry.media_rate_fraction << "\n";
   }

-  return sstr.str();
+  return;
 }

 void Box_elst::derive_box_version()
diff --git a/libheif/sequences/seq_boxes.h b/libheif/sequences/seq_boxes.h
index 8ab02788..cf4761fc 100644
--- a/libheif/sequences/seq_boxes.h
+++ b/libheif/sequences/seq_boxes.h
@@ -38,7 +38,7 @@ public:
     set_short_type(fourcc(type));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

 protected:
   Error parse(BitstreamRange& range, const heif_security_limits*) override;
@@ -62,7 +62,7 @@ public:
     set_short_type(fourcc("mvhd"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Movie Header"; }

@@ -142,7 +142,7 @@ public:
     Track_size_is_aspect_ratio = 0x08
   };

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Track Header"; }

@@ -209,7 +209,7 @@ public:
     set_short_type(fourcc("mdhd"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Media Header"; }

@@ -258,7 +258,7 @@ public:
     set_flags(1);
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Video Media Header"; }

@@ -282,7 +282,7 @@ public:
     set_flags(1);
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Null Media Header"; }

@@ -310,7 +310,7 @@ public:
     set_short_type(fourcc("stsd"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Description"; }

@@ -348,7 +348,7 @@ public:
     set_short_type(fourcc("stts"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Decoding Time to Sample"; }

@@ -394,7 +394,7 @@ public:
     set_short_type(fourcc("ctts"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Composition Time to Sample"; }

@@ -434,7 +434,7 @@ public:
     set_short_type(fourcc("stsc"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample to Chunk"; }

@@ -478,7 +478,7 @@ public:
     set_short_type(fourcc("stco"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Offset"; }

@@ -511,7 +511,7 @@ public:
     set_short_type(fourcc("stsz"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Size"; }

@@ -546,7 +546,7 @@ public:
     set_short_type(fourcc("stss"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sync Sample"; }

@@ -585,7 +585,7 @@ public:
     set_short_type(fourcc("ccst"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Coding Constraints"; }

@@ -610,7 +610,7 @@ public:
     set_short_type(fourcc("auxi"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Auxiliary Info Type"; }

@@ -659,7 +659,7 @@ struct VisualSampleEntry {

   Error write(StreamWriter& writer) const;

-  std::string dump(Indent&) const;
+  void dump(std::ostream&, Indent&, bool full_log) const;
 };


@@ -667,7 +667,7 @@ class Box_VisualSampleEntry : public Box {
 public:
   Error write(StreamWriter& writer) const override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const VisualSampleEntry& get_VisualSampleEntry_const() const { return m_visualSampleEntry; }

@@ -690,7 +690,7 @@ public:

   Error write(StreamWriter& writer) const override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "URI Meta Sample Entry"; }

@@ -717,7 +717,7 @@ public:

   Error write(StreamWriter& writer) const override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "URI"; }

@@ -739,7 +739,7 @@ public:

   void derive_box_version() override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample to Group"; }

@@ -800,7 +800,7 @@ public:

   void derive_box_version() override;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Group Description"; }

@@ -831,7 +831,7 @@ public:
     set_short_type(fourcc("btrt"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Bitrate"; }

@@ -870,7 +870,7 @@ public:

   uint32_t get_num_samples() const { return m_num_samples; }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Auxiliary Information Sizes"; }

@@ -910,7 +910,7 @@ public:

   uint64_t get_chunk_offset(uint32_t idx) const;

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Sample Auxiliary Information Offsets"; }

@@ -942,7 +942,7 @@ public:
     set_short_type(fourcc("sdtp"));
   }

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Independent and Disposable Samples"; }

@@ -977,7 +977,7 @@ public:
     std::vector<uint32_t> to_track_id;
   };

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Track Reference"; }

@@ -1022,7 +1022,7 @@ public:
     Repeat_EditList = 0x01
   };

-  std::string dump(Indent&) const override;
+  void dump(std::ostream&, Indent&, bool full_log) const override;

   const char* debug_box_name() const override { return "Edit List"; }

diff --git a/tests/avc_box.cc b/tests/avc_box.cc
index 38e6200f..9d3191d7 100644
--- a/tests/avc_box.cc
+++ b/tests/avc_box.cc
@@ -63,7 +63,7 @@ TEST_CASE("avcC") {
   REQUIRE(avcC->getPictureParameterSets().size() == 1);
   REQUIRE(avcC->getPictureParameterSets()[0].size() == 7);
   Indent indent;
-  std::string dumpResult = box->dump(indent);
+  std::string dumpResult = box->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: avcC -----\n"
                         "size: 52   (header size: 8)\n"
                         "configuration_version: 1\n"
diff --git a/tests/idat.cc b/tests/idat.cc
index af2415db..767eaca0 100644
--- a/tests/idat.cc
+++ b/tests/idat.cc
@@ -46,6 +46,6 @@ TEST_CASE("idat bad") {
     box->get_type();
     box->get_type_string();
     Indent indent;
-    box->dump(indent);
+    box->dump_to_string(indent);
   }
 }
diff --git a/tests/jpeg2000.cc b/tests/jpeg2000.cc
index 143675f5..95687d2e 100644
--- a/tests/jpeg2000.cc
+++ b/tests/jpeg2000.cc
@@ -58,7 +58,7 @@ TEST_CASE( "cdef" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = cdef->dump(indent);
+    std::string dump_output = cdef->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cdef -----\nsize: 0   (header size: 0)\nchannel_index: 1, channel_type: 2, channel_association: 0\n");
 }

@@ -92,7 +92,7 @@ TEST_CASE( "cmap" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = cmap->dump(indent);
+    std::string dump_output = cmap->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmap -----\nsize: 0   (header size: 0)\ncomponent_index: 2, mapping_type: 1, palette_colour: 3\ncomponent_index: 4, mapping_type: 0, palette_colour: 0\n");
 }

@@ -105,7 +105,7 @@ TEST_CASE( "pclr empty" )
     REQUIRE(pclr->get_bit_depths().size() == 0);

     Indent indent;
-    std::string dump_output = pclr->dump(indent);
+    std::string dump_output = pclr->dump_to_string(indent);
     REQUIRE(dump_output == "Box: pclr -----\nsize: 0   (header size: 0)\nNE: 0, NPC: 0, B: \n");

     StreamWriter writer;
@@ -139,7 +139,7 @@ TEST_CASE( "pclr" )
     std::vector<uint8_t> expected = {0x00, 0x00, 0x00, 0x14, 'p', 'c', 'l', 'r', 0x00, 0x02, 0x03, 0x07, 0x07, 0x07, 0x01, 0x02, 0x03, 0xFF, 0xFE, 0xFD};
     REQUIRE(bytes == expected);
     Indent indent;
-    std::string dump_output = pclr->dump(indent);
+    std::string dump_output = pclr->dump_to_string(indent);
     REQUIRE(dump_output == "Box: pclr -----\nsize: 0   (header size: 0)\nNE: 2, NPC: 3, B: 8, 8, 8, \n");
 }

@@ -167,7 +167,7 @@ TEST_CASE( "pclr 12 bit" )
     std::vector<uint8_t> expected = {0x00, 0x00, 0x00, 0x1A, 'p', 'c', 'l', 'r', 0x00, 0x02, 0x03, 0x0B, 0x0B, 0x0B, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x0F, 0xFF, 0x0F, 0xFE, 0x0F, 0xFD};
     REQUIRE(bytes == expected);
     Indent indent;
-    std::string dump_output = pclr->dump(indent);
+    std::string dump_output = pclr->dump_to_string(indent);
     REQUIRE(dump_output == "Box: pclr -----\nsize: 0   (header size: 0)\nNE: 2, NPC: 3, B: 12, 12, 12, \n");
 }

@@ -193,7 +193,7 @@ TEST_CASE( "j2kL" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = j2kL->dump(indent);
+    std::string dump_output = j2kL->dump_to_string(indent);
     REQUIRE(dump_output == "Box: j2kL -----\nsize: 0   (header size: 0)\nlayer_id: 1, discard_levels: 2, decode_layers: 3\n");
 }

diff --git a/tests/mini_box.cc b/tests/mini_box.cc
index 640f4986..87275a22 100644
--- a/tests/mini_box.cc
+++ b/tests/mini_box.cc
@@ -70,7 +70,7 @@ TEST_CASE("mini")
   REQUIRE(ftyp->get_minor_version() == fourcc("avif"));
   REQUIRE(ftyp->list_brands().size() == 0);
   Indent indent;
-  std::string dumpResult = box->dump(indent);
+  std::string dumpResult = box->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: ftyp ----- (File Type)\n"
                         "size: 16   (header size: 8)\n"
                         "major brand: mif3\n"
@@ -97,7 +97,7 @@ TEST_CASE("mini")
   REQUIRE((int)(mini->get_main_item_codec_config().data()[1]) == 0x20);
   REQUIRE((int)(mini->get_main_item_codec_config().data()[2]) == 0x00);
   REQUIRE((int)(mini->get_main_item_codec_config().data()[3]) == 0x00);
-  dumpResult = box->dump(indent);
+  dumpResult = box->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: mini -----\n"
                         "size: 74   (header size: 8)\n"
                         "version: 0\n"
@@ -404,7 +404,7 @@ TEST_CASE("check mini+alpha version")
   REQUIRE((int)(mini->get_main_item_codec_config().data()[2]) == 0x00);
   REQUIRE((int)(mini->get_main_item_codec_config().data()[3]) == 0x00);
   Indent indent;
-  std::string dumpResult = mini->dump(indent);
+  std::string dumpResult = mini->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: mini -----\n"
                         "size: 1923   (header size: 8)\n"
                         "version: 0\n"
@@ -456,7 +456,7 @@ TEST_CASE("check mini+exif+xmp version")
   REQUIRE((int)(mini->get_main_item_codec_config().data()[2]) == 0x00);
   REQUIRE((int)(mini->get_main_item_codec_config().data()[3]) == 0x00);
   Indent indent;
-  std::string dumpResult = mini->dump(indent);
+  std::string dumpResult = mini->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: mini -----\n"
                         "size: 6294   (header size: 8)\n"
                         "version: 0\n"
@@ -504,7 +504,7 @@ TEST_CASE("check heif mini")
   REQUIRE(mini->get_height() == 256);
   REQUIRE(mini->get_main_item_codec_config().size() == 113);
   Indent indent;
-  std::string dumpResult = mini->dump(indent);
+  std::string dumpResult = mini->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: mini -----\n"
                         "size: 19229   (header size: 8)\n"
                         "version: 0\n"
diff --git a/tests/omaf_boxes.cc b/tests/omaf_boxes.cc
index 27c0280d..7f6fd844 100644
--- a/tests/omaf_boxes.cc
+++ b/tests/omaf_boxes.cc
@@ -49,7 +49,7 @@ TEST_CASE("prfr") {
   std::shared_ptr<Box_prfr> prfr = std::dynamic_pointer_cast<Box_prfr>(box);
   REQUIRE(prfr->get_omaf_image_projection() == heif_omaf_image_projection_cube_map);
   Indent indent;
-  std::string dumpResult = box->dump(indent);
+  std::string dumpResult = box->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: prfr ----- (Projection Format)\n"
                         "size: 13   (header size: 12)\n"
                         "projection_type: cube-map\n");
diff --git a/tests/uncompressed_box.cc b/tests/uncompressed_box.cc
index 21b3fe37..467d61ad 100644
--- a/tests/uncompressed_box.cc
+++ b/tests/uncompressed_box.cc
@@ -54,7 +54,7 @@ TEST_CASE( "cmpd" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = cmpd->dump(indent);
+    std::string dump_output = cmpd->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpd -----\nsize: 0   (header size: 0)\ncomponent_type: Y\n");
 }

@@ -93,7 +93,7 @@ TEST_CASE( "cmpd_multi" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = cmpd->dump(indent);
+    std::string dump_output = cmpd->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpd -----\nsize: 0   (header size: 0)\ncomponent_type: red\ncomponent_type: green\ncomponent_type: blue\n");
 }

@@ -127,7 +127,7 @@ TEST_CASE( "cmpd_custom" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = cmpd->dump(indent);
+    std::string dump_output = cmpd->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpd -----\nsize: 0   (header size: 0)\ncomponent_type: 0x8000\n| component_type_uri: http://example.com/custom_component_uri\ncomponent_type: 0x8002\n| component_type_uri: http://example.com/another_custom_component_uri\n");
 }

@@ -214,7 +214,7 @@ TEST_CASE( "uncC" )
     REQUIRE(bytes == expected);

     Indent indent;
-    std::string dump_output = uncC->dump(indent);
+    std::string dump_output = uncC->dump_to_string(indent);
     REQUIRE(dump_output == "Box: uncC -----\nsize: 0   (header size: 0)\nprofile: 1919378017 (rgba)\ncomponent_index: 0\n| component_bit_depth: 8\n| component_format: unsigned\n| component_align_size: 0\ncomponent_index: 1\n| component_bit_depth: 8\n| component_format: unsigned\n| component_align_size: 0\ncomponent_index: 2\n| component_bit_depth: 8\n| component_format: unsigned\n| component_align_size: 0\ncomponent_index: 3\n| component_bit_depth: 8\n| component_format: unsigned\n| component_align_size: 0\nsampling_type: no subsampling\ninterleave_type: pixel\nblock_size: 0\ncomponents_little_endian: 0\nblock_pad_lsb: 0\nblock_little_endian: 0\nblock_reversed: 0\npad_unknown: 0\npixel_size: 0\nrow_align_size: 0\ntile_align_size: 0\nnum_tile_cols: 1\nnum_tile_rows: 1\n");
 }

@@ -245,7 +245,7 @@ TEST_CASE("uncC_parse") {
   REQUIRE(uncC->get_number_of_tile_columns() == 2);
   REQUIRE(uncC->get_number_of_tile_rows() == 3);
   Indent indent;
-  std::string dumpResult = box->dump(indent);
+  std::string dumpResult = box->dump_to_string(indent);
   REQUIRE(dumpResult == "Box: uncC -----\n"
                         "size: 64   (header size: 12)\n"
                         "profile: 1919378017 (rgba)\n"
@@ -382,7 +382,7 @@ TEST_CASE("cmpC_defl") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = cmpC->dump(indent);
+    std::string dump_output = cmpC->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpC -----\nsize: 17   (header size: 12)\ncompression_type: defl\ncompressed_entity_type: 0\n");

 }
@@ -418,7 +418,7 @@ TEST_CASE("cmpC_zlib") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = cmpC->dump(indent);
+    std::string dump_output = cmpC->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpC -----\nsize: 17   (header size: 12)\ncompression_type: zlib\ncompressed_entity_type: 2\n");

 }
@@ -453,7 +453,7 @@ TEST_CASE("cmpC_brot") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = cmpC->dump(indent);
+    std::string dump_output = cmpC->dump_to_string(indent);
     REQUIRE(dump_output == "Box: cmpC -----\nsize: 17   (header size: 12)\ncompression_type: brot\ncompressed_entity_type: 1\n");

   }
@@ -492,7 +492,7 @@ TEST_CASE("icef_24_8_bit") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = icef->dump(indent);
+    std::string dump_output = icef->dump_to_string(indent);
     REQUIRE(dump_output == "Box: icef -----\nsize: 25   (header size: 12)\nnum_compressed_units: 2\nunit_offset: 2563, unit_size: 3\nunit_offset: 131850, unit_size: 7\n");
 }

@@ -534,7 +534,7 @@ TEST_CASE("icef_0_16_bit") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = icef->dump(indent);
+    std::string dump_output = icef->dump_to_string(indent);
     REQUIRE(dump_output == "Box: icef -----\nsize: 21   (header size: 12)\nnum_compressed_units: 2\nunit_offset: 0, unit_size: 16387\nunit_offset: 16387, unit_size: 2567\n");
 }

@@ -576,7 +576,7 @@ TEST_CASE("icef_32bit") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = icef->dump(indent);
+    std::string dump_output = icef->dump_to_string(indent);
     REQUIRE(dump_output == "Box: icef -----\nsize: 33   (header size: 12)\nnum_compressed_units: 2\nunit_offset: 772, unit_size: 16843267\nunit_offset: 16909066, unit_size: 263431\n");
 }

@@ -620,7 +620,7 @@ TEST_CASE("icef_uint64") {
     REQUIRE(written == byteArray);

     Indent indent;
-    std::string dump_output = icef->dump(indent);
+    std::string dump_output = icef->dump_to_string(indent);
     REQUIRE(dump_output == "Box: icef -----\nsize: 49   (header size: 12)\nnum_compressed_units: 2\nunit_offset: 4294969859, unit_size: 8590000643\nunit_offset: 8590066442, unit_size: 12885165319\n");
 }

@@ -683,7 +683,7 @@ TEST_CASE("cloc")

   // Dump
   Indent indent;
-  std::string dump_output = parsed->dump(indent);
+  std::string dump_output = parsed->dump_to_string(indent);
   REQUIRE(dump_output == "Box: cloc -----\nsize: 13   (header size: 12)\nversion: 0\nflags: 0\nchroma_location: 2 (h=0,   v=0)\n");
 }

@@ -778,7 +778,7 @@ TEST_CASE("splz")

   // Dump
   Indent indent;
-  std::string dump_output = parsed->dump(indent);
+  std::string dump_output = parsed->dump_to_string(indent);
   REQUIRE(dump_output == "Box: splz -----\n"
                          "size: 36   (header size: 12)\n"
                          "version: 0\n"
@@ -880,7 +880,7 @@ TEST_CASE("snuc")

   // Dump
   Indent indent;
-  std::string dump_output = parsed->dump(indent);
+  std::string dump_output = parsed->dump_to_string(indent);
   REQUIRE(dump_output == "Box: snuc -----\n"
                          "size: 45   (header size: 12)\n"
                          "version: 0\n"