0

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

5
  • What error message and stack trace are you getting? Commented Oct 14, 2015 at 18:54
  • @BenjaminHodgson Well, there is no error but "res" reads 0, while it should be 2 Commented Oct 14, 2015 at 18:57
  • Duplicate? stackoverflow.com/questions/14840120/… Commented Oct 14, 2015 at 19:03
  • That answer in "duplicate" did not work. Commented Oct 14, 2015 at 19:14
  • You can always read byte by byte and "assemble" the result as a 32 bit value. Commented Oct 14, 2015 at 19:21

3 Answers 3

6

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
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.