user915783
user915783

Reputation: 699

reading 24 bit binary data in python not working

I have single value(val=2) written as 24 bit data using matlab as:

fid = fopen('.\t1.bin'), 'wb');
fwrite(fid, val, 'bit24', 0);

In a bin viewer, I can see that data (value 2) is stored as 02 00 00. I need to read value as single integer in python. my code below does not work:

    struct_fmt = '=xxx'       
    struct_unpack = struct.Struct(struct_fmt).unpack_from
    with open('.\\t1.bin', mode='rb') as file:
        fileContent = file.read()                
        res = struct_unpack(fileContent)

I also tried

val = struct.unpack('>I',fileContent)

but it give error:

unpack requires a string argument of length 4

What am i doing wrong?
Thanks
sedy

Upvotes: 0

Views: 1867

Answers (3)

westman379
westman379

Reputation: 723

You can use rawutil library to get uint24 value. Here is my function for that:

import rawutil

def get_uint24(input_bytes: bytes, endianess: str) -> int:
  result = rawutil.unpack(endianess + "U", input_bytes)[0]
  return result

Upvotes: 0

heltonbiker
heltonbiker

Reputation: 27605

You can always convert integers to bytes and vice-versa, by accessing individual bytes. Just take care of endianness.

The code below uses a random integer to convert to 24 bit binary and back.

import struct, random

# some number in the range of [0, UInt24.MaxValue]
originalvalue = int (random.random() * 255 ** 3)   

# take each one of its 3 component bytes with bitwise operations
a = (originalvalue & 0xff0000) >> 16
b = (originalvalue & 0x00ff00) >> 8
c = (originalvalue & 0x0000ff)

# byte array to be passed to "struct.pack"
originalbytes = (a,b,c)
print originalbytes

# convert to binary string
binary = struct.pack('3B', *originalbytes)

# convert back from binary string to byte array
rebornbytes = struct.unpack('3B', binary)   ## this is what you want to do!
print rebornbytes

# regenerate the integer
rebornvalue = a << 16 | b << 8 | c
print rebornvalue

Upvotes: 2

bgporter
bgporter

Reputation: 36554

In the Python struct module format characters, x is defined as a pad byte. The format string that you have there says to read in 3 bytes and then discard them.

There's not already a format specifier to handle 24-bit data, so build one yourself:

>>> def unpack_24bit(bytes):
...    return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16)
...
>>> bytes
'\x02\x00\x00'
>>> unpack_24bit(struct.unpack('BBB', bytes))
2

Upvotes: 6

Related Questions