from .struct import Structure as _Structure
from .struct import Field as _Field
from .util import assert_null as _assert_null
+from .util import byte_order as _byte_order
+from .util import need_to_reorder_bytes as _need_to_reorder_bytes
+from .util import checksum as _checksum
# Numpy doesn't support complex integers by default, see
# End IGOR constants and typedefs from IgorBin.h
-# Begin functions from ReadWave.c
-
-def need_to_reorder_bytes(version):
- # If the low order byte of the version field of the BinHeader
- # structure is zero then the file is from a platform that uses
- # different byte-ordering and therefore all data will need to be
- # reordered.
- return version & 0xFF == 0
-
-def byte_order(needToReorderBytes):
- little_endian = _sys.byteorder == 'little'
- if needToReorderBytes:
- little_endian = not little_endian
- if little_endian:
- return '<' # little-endian
- return '>' # big-endian
-
-def version_structs(version, byte_order):
+def _version_structs(version, byte_order):
if version == 1:
bin = BinHeader1
wave = WaveHeader2
wave.set_byte_order(byte_order)
return (bin, wave, checkSumSize)
-def checksum(buffer, byte_order, oldcksum, numbytes):
- x = _numpy.ndarray(
- (numbytes/2,), # 2 bytes to a short -- ignore trailing odd byte
- dtype=_numpy.dtype(byte_order+'h'),
- buffer=buffer)
- oldcksum += x.sum()
- if oldcksum > 2**31: # fake the C implementation's int rollover
- oldcksum %= 2**32
- if oldcksum > 2**31:
- oldcksum -= 2**31
- return oldcksum & 0xffff
-
# Translated from ReadWave()
-def loadibw(filename, strict=True):
+def load(filename, strict=True):
if hasattr(filename, 'read'):
f = filename # filename is actually a stream object
else:
try:
BinHeaderCommon.set_byte_order('=')
b = buffer(f.read(BinHeaderCommon.size))
- version = BinHeaderCommon.unpack_dict_from(b)['version']
- needToReorderBytes = need_to_reorder_bytes(version)
- byteOrder = byte_order(needToReorderBytes)
-
+ version = BinHeaderCommon.unpack_from(b)['version']
+ needToReorderBytes = _need_to_reorder_bytes(version)
+ byteOrder = _byte_order(needToReorderBytes)
+
if needToReorderBytes:
BinHeaderCommon.set_byte_order(byteOrder)
- version = BinHeaderCommon.unpack_dict_from(b)['version']
- bin_struct,wave_struct,checkSumSize = version_structs(version, byteOrder)
+ version = BinHeaderCommon.unpack_from(b)['version']
+ bin_struct,wave_struct,checkSumSize = _version_structs(
+ version, byteOrder)
b = buffer(b + f.read(bin_struct.size + wave_struct.size - BinHeaderCommon.size))
- c = checksum(b, byteOrder, 0, checkSumSize)
+ c = _checksum(b, byteOrder, 0, checkSumSize)
if c != 0:
raise ValueError(
('This does not appear to be a valid Igor binary wave file. '
'Error in checksum: should be 0, is {}.').format(c))
- bin_info = bin_struct.unpack_dict_from(b)
- wave_info = wave_struct.unpack_dict_from(b, offset=bin_struct.size)
+ bin_info = bin_struct.unpack_from(b)
+ wave_info = wave_struct.unpack_from(b, offset=bin_struct.size)
if version in [1,2,3]:
tail = 16 # 16 = size of wData field in WaveHeader2 structure
waveDataSize = bin_info['wfmSize'] - wave_struct.size
labels = str(f.read(size)).split(chr(0)) # split null-delimited strings
bin_info['dimLabels'].append([L for L in labels if len(L) > 0])
if wave_info['type'] == 0: # text wave
- bin_info['sIndices'] = f.read(bin_info['sIndicesSize'])
+ sIndices_data = f.read(bin_info['sIndicesSize'])
+ sIndices_count = bin_info['sIndicesSize']/4
+ bin_info['sIndices'] = _numpy.ndarray(
+ shape=(sIndices_count,),
+ dtype=_numpy.dtype(
+ _numpy.uint32()).newbyteorder(byteOrder),
+ buffer=sIndices_data,
+ order='F',
+ )
if wave_info['type'] == 0: # text wave
# use sIndices to split data into strings
strings = []
start = 0
- for i,string_index in enumerate(bin_info['sIndices']):
- offset = ord(string_index)
+ for i,offset in enumerate(bin_info['sIndices']):
if offset > start:
string = data[start:offset]
strings.append(''.join(chr(x) for x in string))
start = offset
+ elif offset == start:
+ strings.append('')
else:
- assert offset == 0, offset
+ raise ValueError((offset, bin_info['sIndices']))
data = _numpy.array(strings)
shape = [n for n in wave_info['nDim'] if n > 0] or (0,)
data.reshape(shape)
return data, bin_info, wave_info
-def saveibw(filename):
+def save(filename):
raise NotImplementedError