@@ -68,21 +68,21 @@ def read_data_block(darray, fname, data, mmap):
68
68
if mmap is True :
69
69
mmap = 'c'
70
70
enclabel = gifti_encoding_codes .label [darray .encoding ]
71
- dtype = data_type_codes .type [darray .datatype ]
72
71
72
+ if enclabel not in ('ASCII' , 'B64BIN' , 'B64GZ' , 'External' ):
73
+ raise GiftiParseError (f'Unknown encoding { darray .encoding } ' )
74
+
75
+ # Encode the endianness in the dtype
76
+ byteorder = gifti_endian_codes .byteorder [darray .endian ]
77
+ dtype = data_type_codes .dtype [darray .datatype ].newbyteorder (byteorder )
78
+
79
+ shape = tuple (darray .dims )
80
+ order = array_index_order_codes .npcode [darray .ind_ord ]
81
+
82
+ # GIFTI_ENCODING_ASCII
73
83
if enclabel == 'ASCII' :
74
- # GIFTI_ENCODING_ASCII
75
- c = StringIO (data )
76
- da = np .loadtxt (c , dtype = dtype )
77
- # Reshape to dims specified in GiftiDataArray attributes, but preserve
78
- # existing behaviour of loading as 1D for arrays with a dimension of
79
- # length 1
80
- da = da .reshape (darray .dims ).squeeze ()
81
- return da # independent of the endianness
82
- elif enclabel not in ('B64BIN' , 'B64GZ' , 'External' ):
83
- return 0
84
-
85
- # GIFTI_ENCODING_EXTBIN
84
+ return np .loadtxt (StringIO (data ), dtype = dtype , ndmin = 1 ).reshape (shape , order = order )
85
+
86
86
# We assume that the external data file is raw uncompressed binary, with
87
87
# the data type/endianness/ordering specified by the other DataArray
88
88
# attributes
@@ -98,53 +98,41 @@ def read_data_block(darray, fname, data, mmap):
98
98
newarr = None
99
99
if mmap :
100
100
try :
101
- newarr = np .memmap (
101
+ return np .memmap (
102
102
ext_fname ,
103
103
dtype = dtype ,
104
104
mode = mmap ,
105
105
offset = darray .ext_offset ,
106
- shape = tuple (darray .dims ),
106
+ shape = shape ,
107
+ order = order ,
107
108
)
108
109
# If the memmap fails, we ignore the error and load the data into
109
110
# memory below
110
111
except (AttributeError , TypeError , ValueError ):
111
112
pass
112
113
# mmap=False or np.memmap failed
113
114
if newarr is None :
114
- # We can replace this with a call to np.fromfile in numpy>=1.17,
115
- # as an "offset" parameter was added in that version.
116
- with open (ext_fname , 'rb' ) as f :
117
- f .seek (darray .ext_offset )
118
- nbytes = np .prod (darray .dims ) * dtype ().itemsize
119
- buff = f .read (nbytes )
120
- newarr = np .frombuffer (buff , dtype = dtype )
115
+ return np .fromfile (
116
+ ext_fname ,
117
+ dtype = dtype ,
118
+ count = np .prod (darray .dims ),
119
+ offset = darray .ext_offset ,
120
+ ).reshape (shape , order = order )
121
121
122
122
# Numpy arrays created from bytes objects are read-only.
123
123
# Neither b64decode nor decompress will return bytearrays, and there
124
124
# are not equivalents to fobj.readinto to allow us to pass them, so
125
125
# there is not a simple way to avoid making copies.
126
126
# If this becomes a problem, we should write a decoding interface with
127
127
# a tunable chunk size.
128
+ dec = base64 .b64decode (data .encode ('ascii' ))
129
+ if enclabel == 'B64BIN' :
130
+ buff = bytearray (dec )
128
131
else :
129
- dec = base64 .b64decode (data .encode ('ascii' ))
130
- if enclabel == 'B64BIN' :
131
- # GIFTI_ENCODING_B64BIN
132
- buff = bytearray (dec )
133
- else :
134
- # GIFTI_ENCODING_B64GZ
135
- buff = bytearray (zlib .decompress (dec ))
136
- del dec
137
- newarr = np .frombuffer (buff , dtype = dtype )
138
-
139
- sh = tuple (darray .dims )
140
- if len (newarr .shape ) != len (sh ):
141
- newarr = newarr .reshape (sh , order = array_index_order_codes .npcode [darray .ind_ord ])
142
-
143
- # check if we need to byteswap
144
- required_byteorder = gifti_endian_codes .byteorder [darray .endian ]
145
- if required_byteorder in ('big' , 'little' ) and required_byteorder != sys .byteorder :
146
- newarr = newarr .byteswap ()
147
- return newarr
132
+ # GIFTI_ENCODING_B64GZ
133
+ buff = bytearray (zlib .decompress (dec ))
134
+ del dec
135
+ return np .frombuffer (buff , dtype = dtype ).reshape (shape , order = order )
148
136
149
137
150
138
def _str2int (in_str ):
0 commit comments