0

I'm trying to make a GIF analyzer; I'm having problems with reading an arbitrary number of bits as an integer in little endian. Struct is nice for byte-sized arguments, but some of the GIF structures are 3 bit little endian unsigned integers (specifically in the GIF header, http://www.onicos.com/staff/iz/formats/gif.html). what's the best way to invert these numbers?

I have tried reversing the endianness of the entire byte/s with Struct but it doesn't want to invert:

struct.unpack('<'+str(len(string))+'s',string)[0] //does not actually invert
6
  • 3 bit, for palette size and color depth Commented Feb 25, 2013 at 0:22
  • @rsheldii: So you have only 8 different colors? Commented Feb 25, 2013 at 0:25
  • Also, why not let struct extract the bytes and then use bitwise operators to extract specific bits? Commented Feb 25, 2013 at 0:26
  • this is the GIF89a specification. Color depth is measured in bits per color + 1, so there are 8 bits of data per color maximum. Color palette size is measured as 2^(n+1) bytes, so there are 256 bytes for a global color palette maximum. I am currently using Struct to extract the Pack byte, but there are 3-bit structures within this byte which are little endian. I can extract those bits using bitwise operations, but python reads 110 as 7 when it is really 3. if there is a way to reverse a byte in struct I could use that, but I haven't found it Commented Feb 25, 2013 at 0:34
  • @rsheldiii Endian-ness doesn't matter if the vale you're reading is less than a byte. Little-endian means that if a value takes multiple bytes, the least significant byte is stored first (at the lower memory address). If the value fits in one byte, it's the same regardless of endian-ness. You can unpack the whole byte, then do some bitwise operations to extract the bits you need. Commented Feb 25, 2013 at 0:38

1 Answer 1

1

I don't know if you can use struct to do the work on things that are less than a byte in size. But if you're not too worried about speed you could try this function. It takes a number to reverse and a size in bits and returns the reversed result.

def reverse(a,size):
    b = 0
    for i in range(size):
        b <<= 1
        b |= a >> i & 1
    return b

Use it like so:

>>> reverse(3,3) # 011 => 110
6
>>> invert(6,3) # 110 => 011
3
>>> invert(4,3) # 100 => 001
1
>>> invert(5,3) # 101 => 111
5
>>> 

Obviously you still need to extract the relevant bits into a number using struct but this should take care of the endianness issue

Sign up to request clarification or add additional context in comments.

1 Comment

thank you, it's been so ling since I've worked with binary data, this was much better than what I would have wrote to reverse bits

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.