Developer documentation
Version 3.0.3-105-gd3941f44
csa_entry.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_csa_entry_h__
18#define __file_dicom_csa_entry_h__
19
20#include "datatype.h"
21#include "raw.h"
22#include "types.h"
23#include "file/dicom/element.h"
24
25namespace MR {
26 namespace File {
27 namespace Dicom {
28
30 public:
31 CSAEntry (const uint8_t* start_p, const uint8_t* end_p, bool output_fields = false) :
32 start (start_p),
33 end (end_p),
34 print (output_fields),
35 cnum (0)
36 {
37 if (strncmp ("SV10", (const char*) start, 4)) {
38 DEBUG ("Siemens CSA entry does not start with \"SV10\"; ignoring");
39 num = 0;
40 next = end;
41 } else {
42 const uint8_t* const unused1 = start+4;
43 if (unused1[0] != 0x04U || unused1[1] != 0x03U || unused1[2] != 0x02U || unused1[3] != 0x01U)
44 DEBUG ("WARNING: CSA2 \'unused1\' int8 field contains unexpected data");
45 num = Raw::fetch_LE<uint32_t> (start+8);
46 const uint32_t unused2 = Raw::fetch_LE<uint32_t> (start+12);
47 if (unused2 != 77)
48 DEBUG ("CSA2 \'unused2\' integer field contains " + str(unused2) + "; expected 77");
49 next = start + 16;
50 }
51 }
52
53
54 bool parse () {
55 if (cnum >= num)
56 return false;
57 start = next;
58 if (start >= end + 84)
59 return false;
60 strncpy (name, (const char*) start, 64);
61 Raw::fetch_LE<uint32_t> (start+64); // vm
62 strncpy (vr, (const char*) start+68, 4);
63 Raw::fetch_LE<uint32_t> (start+72); // syngodt
64 nitems = Raw::fetch_LE<uint32_t> (start+76);
65 const int32_t xx = Raw::fetch_LE<int32_t> (start+80);
66 if (!(xx == 77 || xx == 205))
67 DEBUG ("CSA tag \'xx\' integer field contains " + str(xx) + "; expected 77 or 205");
68 if (print)
69 fprintf (stdout, " [CSA] %s: ", name);
70 next = start + 84;
71 if (next + 4 >= end)
72 return false;
73
74 for (uint32_t m = 0; m < nitems; m++) {
75 uint32_t length = Raw::fetch_LE<uint32_t> (next);
76 size_t size = 16 + 4*((length+3)/4);
77 if (next + size > end)
78 return false;
79 if (print)
80 fprintf (stdout, "%.*s ", length, (const char*) next+16);
81 next += size;
82 }
83 if (print)
84 fprintf (stdout, "\n");
85
86 cnum++;
87 return true;
88 }
89
90 const char* key () const { return name; }
91
92 uint32_t num_items() const { return nitems; }
93 uint32_t size() const { return num; }
94
95 int get_int () const {
96 const uint8_t* p = start + 84;
97 for (uint32_t m = 0; m < nitems; m++) {
98 uint32_t length = Raw::fetch_LE<uint32_t> (p);
99 if (length)
100 return to<int> (std::string (reinterpret_cast<const char*> (p)+16, 4*((length+3)/4)));
101 p += 16 + 4*((length+3)/4);
102 }
103 return 0;
104 }
105
107 const uint8_t* p = start + 84;
108 for (uint32_t m = 0; m < nitems; m++) {
109 uint32_t length = Raw::fetch_LE<uint32_t> (p);
110 if (length)
111 return to<default_type> (std::string (reinterpret_cast<const char*> (p)+16, 4*((length+3)/4)));
112 p += 16 + 4*((length+3)/4);
113 }
114 return NaN;
115 }
116
117 template <typename Container>
118 void get_float (Container& v) const {
119 const uint8_t* p = start + 84;
120 if (nitems < v.size())
121 DEBUG ("CSA entry contains fewer items than expected - trailing entries will be set to NaN");
122 for (uint32_t m = 0; m < std::min<size_t> (nitems, v.size()); m++) {
123 uint32_t length = Raw::fetch_LE<uint32_t> (p);
124 v[m] = length ? to<default_type> (std::string (reinterpret_cast<const char*> (p)+16, 4*((length+3)/4))) : NaN;
125 p += 16 + 4*((length+3)/4);
126 }
127 for (uint32_t m = nitems; m < v.size(); ++m)
128 v[m] = NaN;
129 }
130
132 vector<std::string> result;
133 const uint8_t* p = start + 84;
134 for (uint32_t m = 0; m < nitems; m++) {
135 const uint32_t length = Raw::fetch_LE<uint32_t> (p);
136 std::string s (reinterpret_cast<const char*> (p)+16, length);
137 result.push_back (std::move (s));
138 p += 16 + 4*((length+3)/4);
139 }
140 return result;
141 }
142
143 friend std::ostream& operator<< (std::ostream& stream, const CSAEntry& item) {
144 stream << "[CSA] " << item.name << " (" + str(item.nitems) + " items):";
145 const uint8_t* next = item.start + 84;
146
147 for (uint32_t m = 0; m < item.nitems; m++) {
148 uint32_t length = Raw::fetch_LE<uint32_t> (next);
149 size_t size = 16 + 4*((length+3)/4);
150 while (length > 0 && !next[16+length-1])
151 length--;
152 stream << " ";
153 stream.write (reinterpret_cast<const char*> (next)+16, length);
154 next += size;
155 }
156 stream << "\n";
157
158 return stream;
159 }
160
161
162 protected:
163 const uint8_t* start;
164 const uint8_t* next;
165 const uint8_t* end;
166 bool print;
167 char name[65], vr[5];
168 uint32_t nitems, num, cnum;
169
170 };
171
172
173
174
175
176 }
177 }
178}
179
180#endif
181
182
Definition: csa_entry.h:29
char vr[5]
Definition: csa_entry.h:167
uint32_t size() const
Definition: csa_entry.h:93
bool parse()
Definition: csa_entry.h:54
int get_int() const
Definition: csa_entry.h:95
uint32_t num
Definition: csa_entry.h:168
uint32_t cnum
Definition: csa_entry.h:168
char name[65]
Definition: csa_entry.h:167
CSAEntry(const uint8_t *start_p, const uint8_t *end_p, bool output_fields=false)
Definition: csa_entry.h:31
bool print
Definition: csa_entry.h:166
void get_float(Container &v) const
Definition: csa_entry.h:118
default_type get_float() const
Definition: csa_entry.h:106
const uint8_t * next
Definition: csa_entry.h:164
uint32_t nitems
Definition: csa_entry.h:168
const uint8_t * end
Definition: csa_entry.h:165
vector< std::string > get_string() const
Definition: csa_entry.h:131
friend std::ostream & operator<<(std::ostream &stream, const CSAEntry &item)
Definition: csa_entry.h:143
uint32_t num_items() const
Definition: csa_entry.h:92
const uint8_t * start
Definition: csa_entry.h:163
const char * key() const
Definition: csa_entry.h:90
#define DEBUG(msg)
Definition: exception.h:75
#define NOMEMALIGN
Definition: memory.h:22
PointType::Scalar length(const vector< PointType > &tck)
Definition: streamline.h:134
Definition: base.h:24
double default_type
the default type used throughout MRtrix
Definition: types.h:228
std::string str(const T &value, int precision=0)
Definition: mrtrix.h:247
constexpr default_type NaN
Definition: types.h:230
Item item