Skip to content

Commit cbc7dff

Browse files
committed
RF,BF: Modify read_data_block so that the GiftiDataArray is passed in, rather
than all of its attributes as separate args. Also pass in name of file being parsed, in case data is to be loaded from an external file
1 parent d7cc23e commit cbc7dff

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

nibabel/gifti/parse_gifti_fast.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import sys
1212
import warnings
1313
import zlib
14+
import os.path as op
1415
from io import StringIO
1516
from xml.parsers.expat import ExpatError
1617

@@ -30,16 +31,27 @@ class GiftiParseError(ExpatError):
3031
""" Gifti-specific parsing error """
3132

3233

33-
def read_data_block(encoding,
34-
endian,
35-
ordering,
36-
datatype,
37-
shape,
38-
data,
39-
darray):
40-
""" Tries to unzip, decode, parse the funny string data """
41-
enclabel = gifti_encoding_codes.label[encoding]
42-
dtype = data_type_codes.type[datatype]
34+
def read_data_block(darray, fname, data):
35+
"""Parses data from a <Data> element, or loads from an external file.
36+
37+
Parameters
38+
----------
39+
darray : GiftiDataArray
40+
GiftiDataArray object representing the parent <DataArray> of this
41+
<Data> element
42+
43+
fname : str or None
44+
Name of GIFTI file being loaded, or None if in-memory
45+
46+
data : str or None
47+
Data to parse, or None if data is in an external file
48+
49+
Returns
50+
-------
51+
numpy.ndarray containing the parsed data
52+
"""
53+
enclabel = gifti_encoding_codes.label[darray.encoding]
54+
dtype = data_type_codes.type[darray.datatype]
4355

4456
if enclabel == 'ASCII':
4557
# GIFTI_ENCODING_ASCII
@@ -54,9 +66,15 @@ def read_data_block(encoding,
5466
# the data type/endianness/ordering specified by the other DataArray
5567
# attributes
5668
if enclabel == 'External':
57-
with open(darray.ext_fname, 'rb') as f:
69+
if fname is None:
70+
raise GiftiParseError('ExternalFileBinary is not supported '
71+
'when loading from in-memory XML')
72+
ext_fname = op.join(op.dirname(fname), darray.ext_fname)
73+
if not op.exists(ext_fname):
74+
raise GiftiParseError('Cannot locate external file ' + ext_fname)
75+
with open(ext_fname, 'rb') as f:
5876
f.seek(darray.ext_offset)
59-
nbytes = np.prod(shape) * dtype().itemsize
77+
nbytes = np.prod(darray.dims) * dtype().itemsize
6078
buff = f.read(nbytes)
6179

6280
# Numpy arrays created from bytes objects are read-only.
@@ -75,13 +93,14 @@ def read_data_block(encoding,
7593
buff = bytearray(zlib.decompress(dec))
7694
del dec
7795

78-
sh = tuple(shape)
96+
sh = tuple(darray.dims)
7997
newarr = np.frombuffer(buff, dtype=dtype)
8098
if len(newarr.shape) != len(sh):
81-
newarr = newarr.reshape(sh, order=array_index_order_codes.npcode[ordering])
99+
newarr = newarr.reshape(
100+
sh, order=array_index_order_codes.npcode[darray.ind_ord])
82101

83102
# check if we need to byteswap
84-
required_byteorder = gifti_endian_codes.byteorder[endian]
103+
required_byteorder = gifti_endian_codes.byteorder[darray.endian]
85104
if (required_byteorder in ('big', 'little') and
86105
required_byteorder != sys.byteorder):
87106
newarr = newarr.byteswap()
@@ -339,10 +358,7 @@ def flush_chardata(self):
339358
c.close()
340359

341360
elif self.write_to == 'Data':
342-
da_tmp = self.img.darrays[-1]
343-
da_tmp.data = read_data_block(da_tmp.encoding, da_tmp.endian,
344-
da_tmp.ind_ord, da_tmp.datatype,
345-
da_tmp.dims, data, self.da)
361+
self.da.data = read_data_block(self.da, self.fname, data)
346362
# update the endianness according to the
347363
# current machine setting
348364
self.endian = gifti_endian_codes.code[sys.byteorder]

0 commit comments

Comments
 (0)