Developer documentation
Version 3.0.3-105-gd3941f44
raw.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 __raw_h__
18#define __raw_h__
19
23#include <atomic>
24
25#include "mrtrix.h"
26
27#define BITMASK 0x01U << 7
28
29#ifdef BYTE_ORDER_IS_BIG_ENDIAN
30#define MRTRIX_IS_BIG_ENDIAN true
31#define TO_LE(v) swap(v)
32#define TO_BE(v) v
33#else
34#define MRTRIX_IS_BIG_ENDIAN false
35#define TO_LE(v) v
36#define TO_BE(v) swap(v)
37#endif
38
39namespace MR
40{
41
45 namespace ByteOrder
46 {
47
48 template <typename ValueType>
49 inline typename std::enable_if<std::is_fundamental<ValueType>::value && sizeof(ValueType) == 1, ValueType>::type swap (ValueType v) {
50 return v;
51 }
52
53 template <typename ValueType>
54 inline typename std::enable_if<std::is_fundamental<ValueType>::value && sizeof(ValueType) == 2, ValueType>::type swap (ValueType v) {
55 union {
56 ValueType v;
57 uint8_t i[2];
58 } val = { v };
59 std::swap (val.i[0], val.i[1]);
60 return val.v;
61 }
62
63 template <typename ValueType>
64 inline typename std::enable_if<std::is_fundamental<ValueType>::value && sizeof(ValueType) == 4, ValueType>::type swap (ValueType v) {
65 union {
66 ValueType v;
67 uint8_t i[4];
68 } val = { v };
69 std::swap (val.i[0], val.i[3]);
70 std::swap (val.i[1], val.i[2]);
71 return val.v;
72 }
73
74 template <typename ValueType>
75 inline typename std::enable_if<std::is_fundamental<ValueType>::value && sizeof(ValueType) == 8, ValueType>::type swap (ValueType v) {
76 union {
77 ValueType v;
78 uint8_t i[8];
79 } val = { v };
80 std::swap (val.i[0], val.i[7]);
81 std::swap (val.i[1], val.i[6]);
82 std::swap (val.i[2], val.i[5]);
83 std::swap (val.i[3], val.i[4]);
84 return val.v;
85 }
86
87 template <typename ValueType>
88 inline typename std::enable_if<is_complex<ValueType>::value, ValueType>::type swap (ValueType v) { return { swap (v.real()), swap (v.imag()) }; }
89
90 template <typename ValueType>
91 inline ValueType LE (ValueType v) { return TO_LE (v); }
92
93 template <typename ValueType>
94 inline ValueType BE (ValueType v) { return TO_BE (v); }
95
96 template <typename ValueType>
97 inline ValueType swap (const ValueType value, bool is_big_endian) { return is_big_endian ? BE (value) : LE (value); }
98
99 }
100
101 namespace Raw {
102
103 namespace {
104 template <typename ValueType> ValueType* as (void* p) { return reinterpret_cast<ValueType*> (p); }
105 template <typename ValueType> const ValueType* as (const void* p) { return reinterpret_cast<const ValueType*> (p); }
106 }
107
108
109 // GET from pointer:
110 template <typename ValueType>
111 inline ValueType fetch_LE (const void* address) { return ByteOrder::LE (*as<ValueType> (address)); }
112
113 template <typename ValueType>
114 inline ValueType fetch_BE (const void* address) { return ByteOrder::BE (*as<ValueType> (address)); }
115
116 template <typename ValueType>
117 inline ValueType fetch_ (const void* address, bool is_big_endian = MRTRIX_IS_BIG_ENDIAN) { return ByteOrder::swap (*as<ValueType>(address), is_big_endian); }
118
119 template <typename ValueType>
120 inline ValueType fetch__native (const void* address) { return *as<ValueType>(address); }
121
122 // PUT at pointer:
123 template <typename ValueType>
124 inline void store_LE (const ValueType value, void* address) { *as<ValueType>(address) = ByteOrder::LE (value); }
125
126 template <typename ValueType>
127 inline void store_BE (const ValueType value, void* address) { *as<ValueType>(address) = ByteOrder::BE (value); }
128
129 template <typename ValueType>
130 inline void store (const ValueType value, void* address, bool is_big_endian = MRTRIX_IS_BIG_ENDIAN) { *as<ValueType>(address) = ByteOrder::swap (value, is_big_endian); }
131
132 template <typename ValueType>
133 inline void store_native (const ValueType value, void* address) { *as<ValueType>(address) = value; }
134
135
136
138 template <typename ValueType>
139 inline ValueType fetch_LE (const void* data, size_t i) { return ByteOrder::LE (as<ValueType>(data)[i]); }
140
142 template <typename ValueType>
143 inline ValueType fetch_BE (const void* data, size_t i) { return ByteOrder::BE (as<ValueType>(data)[i]); }
144
146 template <typename ValueType>
147 inline ValueType fetch (const void* data, size_t i, bool is_big_endian = MRTRIX_IS_BIG_ENDIAN) { return ByteOrder::swap (as<ValueType>(data)[i], is_big_endian); }
148
150 template <typename ValueType>
151 inline ValueType fetch_native (const void* data, size_t i) { return as<ValueType>(data)[i]; }
152
153
154
156 template <typename ValueType>
157 inline void store_LE (const ValueType value, void* data, size_t i) { as<ValueType>(data)[i] = ByteOrder::LE (value); }
158
160 template <typename ValueType>
161 inline void store_BE (const ValueType value, void* data, size_t i) { as<ValueType>(data)[i] = ByteOrder::BE (value); }
162
164 template <typename ValueType>
165 inline void store (const ValueType value, void* data, size_t i, bool is_big_endian = MRTRIX_IS_BIG_ENDIAN) { as<ValueType>(data)[i] = ByteOrder::swap (value, is_big_endian); }
166
168 template <typename ValueType>
169 inline void store_native (const ValueType value, void* data, size_t i) { as<ValueType>(data)[i] = value; }
170
171
173
174
175 template <>
176 inline bool fetch_native<bool> (const void* data, size_t i) { return ( as<uint8_t>(data)[i/8]) & (BITMASK >> i%8 ); }
177
178 template <>
179 inline void store_native<bool> (const bool value, void* data, size_t i) {
180 // bit of a hack - assume lock-free atomic operations on bytes, and that
181 // atomic<uint8_t> genuinely is one byte. Both now checked in thread
182 // initialisation (in Thread::__Backend() constructor)
183 std::atomic<uint8_t>* at = reinterpret_cast<std::atomic<uint8_t>*> (as<uint8_t>(data) + (i/8));
184 uint8_t prev = *at, new_value;
185 do {
186 if (value) new_value = prev | (BITMASK >> i%8);
187 else new_value = prev & ~(BITMASK >> i%8);
188 } while (!at->compare_exchange_weak (prev, new_value));
189 }
190
191
192 template <>
193 inline bool fetch<bool> (const void* data, size_t i, bool) { return fetch_native<bool> (data, i); }
194
195 template <>
196 inline void store<bool> (const bool value, void* data, size_t i, bool) { store_native<bool> (value, data, i); }
197
199 }
200
203}
204
205
206#endif
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
Definition: SH.h:233
ValueType BE(ValueType v)
Definition: raw.h:94
ValueType swap(const ValueType value, bool is_big_endian)
Definition: raw.h:97
ValueType LE(ValueType v)
Definition: raw.h:91
std::enable_if< std::is_fundamental< ValueType >::value &&sizeof(ValueType)==1, ValueType >::type swap(ValueType v)
Definition: raw.h:49
ValueType fetch(const void *data, size_t i, bool is_big_endian=false)
fetch value in format is_big_endian from offset i from data
Definition: raw.h:147
void store(const ValueType value, void *address, bool is_big_endian=false)
Definition: raw.h:130
ValueType fetch_BE(const void *address)
Definition: raw.h:114
ValueType fetch_LE(const void *address)
Definition: raw.h:111
ValueType fetch_native(const void *data, size_t i)
fetch value in native format from offset i from data
Definition: raw.h:151
void store_native(const ValueType value, void *address)
Definition: raw.h:133
void store_LE(const ValueType value, void *address)
Definition: raw.h:124
ValueType fetch_(const void *address, bool is_big_endian=false)
Definition: raw.h:117
void store_BE(const ValueType value, void *address)
Definition: raw.h:127
ValueType fetch__native(const void *address)
Definition: raw.h:120
Definition: base.h:24
#define TO_BE(v)
Definition: raw.h:36
#define BITMASK
Definition: raw.h:27
#define TO_LE(v)
Definition: raw.h:35
#define MRTRIX_IS_BIG_ENDIAN
Definition: raw.h:34