Developer documentation
Version 3.0.3-105-gd3941f44
element.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 __file_dicom_element_h__
18#define __file_dicom_element_h__
19
20#include <unordered_map>
21
22#include "memory.h"
23#include "raw.h"
24#include "types.h"
25#include "file/mmap.h"
27
28namespace MR {
29 namespace File {
30 namespace Dicom {
31
32
34 public:
35 Sequence (uint16_t group, uint16_t element, uint8_t* end) : group (group), element (element), end (end) { }
36 uint16_t group, element;
37 uint8_t* end;
38
39 bool is (uint16_t Group, uint16_t Element) const {
40 if (group != Group)
41 return false;
42 return element == Element;
43 }
44 };
45
47 public:
48 Date (const std::string& entry) :
49 year(0), month(0), day(0) {
50 if (entry.size() >= 8) {
51 year = to<uint32_t> (entry.substr (0, 4));
52 month = to<uint32_t> (entry.substr (4, 2));
53 day = to<uint32_t> (entry.substr (6, 2));
54 }
55 if (year < 1000 || month > 12 || day > 31)
56 throw Exception ("Error converting string \"" + entry + "\" to date");
57 }
58 uint32_t year, month, day;
59 friend std::ostream& operator<< (std::ostream& stream, const Date& item);
60 };
61
63 public:
64 Time (const std::string& entry) : Time() {
65 if (entry.size() < 6)
66 throw Exception ("field \"" + entry + "\" is too short to be interpreted as a time");
67 hour = to<uint32_t> (entry.substr (0, 2));
68 minute = to<uint32_t> (entry.substr (2, 2));
69 second = to<uint32_t> (entry.substr (4, 2));
70 fraction = entry.size() > 6 ? to<default_type> (entry.substr (6)) : 0.0;
71 }
73 {
74 if (i < 0.0)
75 throw Exception ("Error converting negative floating-point number to a time");
76 hour = std::floor (i / 3600.0); i -= hour * 3600.0;
77 if (hour >= 24)
78 throw Exception ("Error converting floating-point number to a time: Beyond 24 hours");
79 minute = std::floor (i / 60.0); i -= minute * 60;
80 second = std::floor (i);
81 fraction = i - second;
82 }
83 Time () : hour (0), minute (0), second (0), fraction (0.0) { }
84 operator default_type() const { return (hour*3600.0 + minute*60 + second + fraction); }
85 Time operator- (const Time& t) const { return Time (default_type (*this) - default_type (t)); }
86 uint32_t hour, minute, second;
88 friend std::ostream& operator<< (std::ostream& stream, const Time& item);
89 };
90
91
92
93
94
96 public:
97 typedef enum _Type {
107 OTHER
109
110 uint16_t group, element, VR;
111 uint32_t size;
112 uint8_t* data;
115
116 void set (const std::string& filename, bool force_read = false, bool read_write = false);
117 bool read ();
118
119 bool is (uint16_t Group, uint16_t Element) const {
120 if (group != Group)
121 return false;
122 return element == Element;
123 }
124
125 std::string tag_name () const {
126 if (dict.empty()) init_dict();
127 const char* s = dict[tag()];
128 return (s ? s : "");
129 }
130
131 uint32_t tag () const {
132 union __DICOM_group_element_pair__ { uint16_t s[2]; uint32_t i; } val = { {
133#if MRTRIX_BYTE_ORDER_BIG_ENDIAN
135#else
137#endif
138 } };
139 return val.i;
140 }
141
142
143 size_t offset (uint8_t* address) const {
144 return address - fmap->address();
145 }
146 bool is_big_endian () const {
147 return is_BE;
148 }
149 bool is_new_sequence () const {
150 return VR == VR_SQ || ( group == GROUP_DATA && element == ELEMENT_DATA && size == LENGTH_UNDEFINED );
151 }
152
153 bool ignore_when_parsing () const;
155
156 Type type () const;
160 Date get_date () const;
161 Time get_time () const;
162 std::pair<Date,Time> get_datetime () const;
164
165 int32_t get_int (size_t idx, int32_t default_value = 0) const { auto v (get_int()); return check_get (idx, v.size()) ? v[idx] : default_value; }
166 uint32_t get_uint (size_t idx, uint32_t default_value = 0) const { auto v (get_uint()); return check_get (idx, v.size()) ? v[idx] : default_value; }
167 double get_float (size_t idx, double default_value = 0.0) const { auto v (get_float()); return check_get (idx, v.size()) ? v[idx] : default_value; }
168 std::string get_string (size_t idx, std::string default_value = std::string()) const { auto v (get_string()); return check_get (idx, v.size()) ? v[idx] : default_value; }
169
170 std::string as_string () const;
171
172 size_t level () const { return parents.size(); }
173
174 friend std::ostream& operator<< (std::ostream& stream, const Element& item);
175 static std::string print_header () {
176 return "TYPE GRP ELEM VR SIZE OFFSET NAME CONTENTS\n"
177 "----- ---- ---- -- ------- ------- ------------------------------------- ---------------------------------------\n";
178 }
179
180
181 template <typename VectorType>
182 FORCE_INLINE void check_size (const VectorType v, size_t min_size = 1) {
183 if (v.size() < min_size)
184 error_in_check_size (min_size, v.size());
185 }
186
187 protected:
188
189 std::unique_ptr<File::MMap> fmap;
192
193 uint8_t* next;
194 uint8_t* start;
196
198
199
200 uint16_t get_VR_from_tag_name (const std::string& name) {
201 union {
202 char t[2];
203 uint16_t i;
204 } d = { { name[0], name[1] } };
205 return ByteOrder::BE (d.i);
206 }
207
208 static std::unordered_map<uint32_t, const char*> dict;
209 static void init_dict();
210
211 bool check_get (size_t idx, size_t size) const { if (idx >= size) { error_in_get (idx); return false; } return true; }
212 void error_in_get (size_t idx) const;
213 void error_in_check_size (size_t min_size, size_t actual_size) const;
215
216 static const char* type_as_str[];
217 };
218
219
220
221 }
222 }
223}
224
225#endif
226
Date(const std::string &entry)
Definition: element.h:48
friend std::ostream & operator<<(std::ostream &stream, const Date &item)
double get_float(size_t idx, double default_value=0.0) const
Definition: element.h:167
size_t level() const
Definition: element.h:172
bool is_new_sequence() const
Definition: element.h:149
enum MR::File::Dicom::Element::_Type Type
int32_t get_int(size_t idx, int32_t default_value=0) const
Definition: element.h:165
vector< Sequence > parents
Definition: element.h:113
static std::string print_header()
Definition: element.h:175
FORCE_INLINE void check_size(const VectorType v, size_t min_size=1)
Definition: element.h:182
friend std::ostream & operator<<(std::ostream &stream, const Element &item)
bool check_get(size_t idx, size_t size) const
Definition: element.h:211
std::string get_string(size_t idx, std::string default_value=std::string()) const
Definition: element.h:168
void report_unknown_tag_with_implicit_syntax() const
static std::unordered_map< uint32_t, const char * > dict
Definition: element.h:208
vector< uint8_t * > end_seq
Definition: element.h:197
void error_in_get(size_t idx) const
bool ignore_when_parsing() const
bool is_big_endian() const
Definition: element.h:146
std::pair< Date, Time > get_datetime() const
vector< uint32_t > get_uint() const
void error_in_check_size(size_t min_size, size_t actual_size) const
bool is(uint16_t Group, uint16_t Element) const
Definition: element.h:119
vector< default_type > get_float() const
bool is_in_series_ref_sequence() const
uint32_t tag() const
Definition: element.h:131
uint32_t get_uint(size_t idx, uint32_t default_value=0) const
Definition: element.h:166
vector< std::string > get_string() const
static const char * type_as_str[]
Definition: element.h:216
vector< int32_t > get_int() const
size_t offset(uint8_t *address) const
Definition: element.h:143
std::string tag_name() const
Definition: element.h:125
std::string as_string() const
std::unique_ptr< File::MMap > fmap
Definition: element.h:189
uint16_t get_VR_from_tag_name(const std::string &name)
Definition: element.h:200
void set(const std::string &filename, bool force_read=false, bool read_write=false)
bool is(uint16_t Group, uint16_t Element) const
Definition: element.h:39
Sequence(uint16_t group, uint16_t element, uint8_t *end)
Definition: element.h:35
friend std::ostream & operator<<(std::ostream &stream, const Time &item)
default_type fraction
Definition: element.h:87
Time(const std::string &entry)
Definition: element.h:64
Time(default_type i)
Definition: element.h:72
Time operator-(const Time &t) const
Definition: element.h:85
#define GROUP_DATA
Definition: definitions.h:53
#define ELEMENT_DATA
Definition: definitions.h:58
#define VR_SQ
Definition: definitions.h:23
#define LENGTH_UNDEFINED
Definition: definitions.h:48
constexpr I floor(const T x)
template function with cast to different type
Definition: math.h:75
#define NOMEMALIGN
Definition: memory.h:22
ValueType BE(ValueType v)
Definition: raw.h:94
Definition: base.h:24
double default_type
the default type used throughout MRtrix
Definition: types.h:228
Item item
#define FORCE_INLINE
Definition: types.h:156
const std::string name
Definition: thread.h:108