DGtal 2.1.0
Loading...
Searching...
No Matches
SVOWriter.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17#pragma once
18
19/**
20 * @file SVOWriter.ih
21 * @author Bastien Doignies (bastien.doignies@liris.cnrs.fr)
22 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
23 *
24 * @date 2025/10/20
25 *
26 * This file is part of the DGtal library.
27 */
28
29#include <boost/iostreams/filtering_stream.hpp>
30
31namespace DGtal
32{
33 template<typename Stream, typename Int>
34 static inline void writeBinInt(Stream& stream, Int i)
35 {
36 boost::endian::native_to_little_inplace(i);
37 stream.write(reinterpret_cast<const char*>(&i), sizeof(Int));
38 }
39
40 template<class Space>
41 bool SVOWriter<Space>::exportSVO(const std::string& filename, const DigitalSetByOctree<Space>& octree, bool compressed)
42 {
43 using Octree = DigitalSetByOctree<Space>;
44
45 std::ofstream out(filename.c_str(), std::ios_base::out | std::ios::binary);
46 if (!out) {
47 trace.error() << "Can't open file '" << filename << "'" << std::endl;
48 throw IOException{};
49 }
50
51 // Header:
52 // Even if binary is specified, flux operator writes integer in ascii format.
53 out << "Format: SVO\n";
54 out << "Version: 1\n";
55 out << "Size: " << static_cast<uint64_t>(octree.size()) << '\n';
56 out << "Dim: " << Octree::dimension << '\n';
57 out << "LowerBound:";
58 for (size_t i = 0; i < Space::dimension; ++i)
59 out << " " << octree.domain().lowerBound()[i];
60 out << '\n';
61 out << "UpperBound:";
62 for (size_t i = 0; i < Space::dimension; ++i)
63 out << " " << octree.domain().upperBound()[i];
64 out << "\n";
65 out << "State: " << static_cast<uint64_t>(octree.myState) << '\n';
66 out << "Compression: " << compressed << '\n';
67 out << ".\n";
68
69 const auto& nodes = octree.myNodes;
70
71 boost::iostreams::filtering_ostream outData;
72
73 if (compressed) outData.push(boost::iostreams::zlib_compressor(boost::iostreams::zlib::best_compression));
74 outData.push(out);
75
76 // Technical data of current implementation
77 writeBinInt(outData, static_cast<int64_t>(sizeof(typename Octree::Size)));
78 writeBinInt(outData, static_cast<int64_t>(sizeof(typename Octree::CellIndex)));
79
80 writeBinInt(outData, (typename Octree::Size)nodes.size());
81 for (size_t i = 0; i < nodes.size(); ++i)
82 writeBinInt(outData, (typename Octree::Size)nodes[i].size());
83
84 for (size_t i = 0; i < nodes.size(); ++i)
85 for (size_t j = 0; j < nodes[i].size(); ++j)
86 for (size_t k = 0; k < Octree::CELL_COUNT; ++k)
87 writeBinInt(outData, nodes[i][j].children[k]);
88
89 return true;
90 }
91}