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
rsheldiii
  • 125
  • 1
  • 12
  • 3 bit, for palette size and color depth – rsheldiii Feb 25 '13 at 00:22
  • @rsheldii: So you have only 8 different colors? – Niklas B. Feb 25 '13 at 00:25
  • Also, why not let struct extract the bytes and then use bitwise operators to extract specific bits? – Niklas B. Feb 25 '13 at 00: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 – rsheldiii Feb 25 '13 at 00: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. – Neal Feb 25 '13 at 00:38
  • My answer to the question [Bitwise operations in class inheriting int](http://stackoverflow.com/a/11837243/355230) might be useful to you. – martineau Feb 25 '13 at 00:41

1 Answers1

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

entropy
  • 3,134
  • 20
  • 20
  • 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 – rsheldiii Feb 25 '13 at 00:44