Developer documentation
Version 3.0.3-105-gd3941f44
sparse.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __image_io_sparse_legacy_h__
18#define __image_io_sparse_legacy_h__
19
20#include <cassert>
21#include <cstring>
22#include <fstream>
23#include <typeinfo>
24
25#include "debug.h"
26#include "memory.h"
27#include "file/config.h"
28#include "file/mmap.h"
29#include "file/utils.h"
30#include "image_io/default.h"
31
32
33
34namespace MR
35{
36 namespace ImageIO
37 {
38
39
40
41
42 // A quick description of how the sparse image data are currently stored:
43 // * The data are either after the image data within the same file if extension is .msf, or
44 // in a separate file with the .sdat extension if the image extension if .msh
45 // * The image header must store the fields defined in lib/image/fixel/key.h
46 // These are currently verified on construction of the BufferSparse class. This proved to
47 // be simpler than trying to verify class matching on every interaction with the handler
48 // using templated functions.
49 // * The raw image data consists of unsigned 64-bit integer values. These values correspond to
50 // an offset from the start of the sparse data (wherever that may be) to the sparse data
51 // stored for that particular voxel.
52 // * Wherever sparse data for a voxel is stored, the data begins with a single unsigned 32-bit
53 // integer, which encodes the number of elements in that voxel. The following data is then
54 // a raw memory dump of that many instances of the relevant class type.
55 // * When a sparse image is created for writing, a single unsigned 32-bit integer value of 0
56 // is written at the start of the sparse data. This is done so that uninitialised voxels
57 // can have their raw image value set to 0, and if they are dereferenced, the handler will
58 // indicate that there are zero elements for that voxel.
59 // * The handler does not attempt any type of endianness conversion of the sparse data, so the
60 // systems that read/write the image files must have the same endianness. Since this can't
61 // be determined from the sparse data alone, the relevant Image::Format instead enforces
62 // the endianness of the image data to be native, and assumes that the sparse data has
63 // the same endianness. If the endianness does not match, the file won't open.
64
65
66
67 class SparseLegacy : public Default
68 { MEMALIGN (SparseLegacy)
69 public:
70
71 SparseLegacy (const Header& header, const std::string& sparse_class_name, const size_t sparse_class_size, const File::Entry& entry) :
72 Default (header),
73 class_name (sparse_class_name),
74 class_size (sparse_class_size),
75 file (entry),
76 data_end (0) { }
77
78
80 uint32_t get_numel (const uint64_t offset) const {
81 return *(reinterpret_cast<uint32_t*>(off2mem(offset)));
82 }
83
85
90 uint64_t set_numel (const uint64_t old_offset, const uint32_t numel);
91
93 uint8_t* get (const uint64_t voxel_offset, const size_t index) const {
94 assert (index < get_numel (voxel_offset));
95 const uint64_t offset = sizeof(uint32_t) + (index * class_size);
96 assert (voxel_offset + offset + class_size <= data_end);
97 uint8_t* const ptr = off2mem(voxel_offset) + offset;
98 return ptr;
99 }
100
101
102 const std::string& get_class_name() const { return class_name; }
103 size_t get_class_size() const { return class_size; }
104
105
106 protected:
107 virtual void load (const Header&, size_t);
108 virtual void unload (const Header&);
109
110 const std::string class_name;
111 const size_t class_size;
113 uint64_t data_end;
114 std::unique_ptr<File::MMap> mmap;
115
116
117 uint64_t size() const { return mmap ? mmap->size() : 0; }
118
119 // Convert a file position offset (as read from the image data) to a pointer to the relevant sparsely-stored data
120 uint8_t* off2mem (const uint64_t offset) const { assert (mmap); return mmap->address() + offset; }
121
122
123 };
124
125
126
127 }
128}
129
130#endif
131
132
Definition: entry.h:29
Default(const Header &header)
Definition: default.h:32
virtual void load(const Header &, size_t)
uint64_t size() const
Definition: sparse.h:117
const std::string class_name
Definition: sparse.h:110
uint8_t * off2mem(const uint64_t offset) const
Definition: sparse.h:120
const File::Entry file
Definition: sparse.h:112
const size_t class_size
Definition: sparse.h:111
std::unique_ptr< File::MMap > mmap
Definition: sparse.h:114
virtual void unload(const Header &)
index_type offset
Definition: loop.h:33
Definition: base.h:24
size_t index