17#ifndef __file_dicom_csa_entry_h__
18#define __file_dicom_csa_entry_h__
31 CSAEntry (
const uint8_t* start_p,
const uint8_t* end_p,
bool output_fields =
false) :
34 print (output_fields),
37 if (strncmp (
"SV10", (
const char*)
start, 4)) {
38 DEBUG (
"Siemens CSA entry does not start with \"SV10\"; ignoring");
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);
48 DEBUG (
"CSA2 \'unused2\' integer field contains " +
str(unused2) +
"; expected 77");
61 Raw::fetch_LE<uint32_t> (
start+64);
62 strncpy (
vr, (
const char*)
start+68, 4);
63 Raw::fetch_LE<uint32_t> (
start+72);
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");
69 fprintf (stdout,
" [CSA] %s: ",
name);
74 for (uint32_t m = 0; m <
nitems; m++) {
75 uint32_t
length = Raw::fetch_LE<uint32_t> (
next);
80 fprintf (stdout,
"%.*s ",
length, (
const char*)
next+16);
84 fprintf (stdout,
"\n");
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);
100 return to<int> (std::string (
reinterpret_cast<const char*
> (p)+16, 4*((
length+3)/4)));
101 p += 16 + 4*((
length+3)/4);
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);
111 return to<default_type> (std::string (
reinterpret_cast<const char*
> (p)+16, 4*((
length+3)/4)));
112 p += 16 + 4*((
length+3)/4);
117 template <
typename Container>
119 const uint8_t* p =
start + 84;
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);
127 for (uint32_t m =
nitems; m < v.size(); ++m)
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);
144 stream <<
"[CSA] " <<
item.name <<
" (" +
str(
item.nitems) +
" items):";
145 const uint8_t*
next =
item.start + 84;
147 for (uint32_t m = 0; m <
item.nitems; m++) {
148 uint32_t
length = Raw::fetch_LE<uint32_t> (
next);
153 stream.write (
reinterpret_cast<const char*
> (
next)+16,
length);
CSAEntry(const uint8_t *start_p, const uint8_t *end_p, bool output_fields=false)
void get_float(Container &v) const
default_type get_float() const
vector< std::string > get_string() const
friend std::ostream & operator<<(std::ostream &stream, const CSAEntry &item)
uint32_t num_items() const
PointType::Scalar length(const vector< PointType > &tck)
double default_type
the default type used throughout MRtrix
std::string str(const T &value, int precision=0)
constexpr default_type NaN