Search code examples
pythonpngfile-formatbit

PNG Chunk type-code Bit #5


I'm trying to write my own little PNG reader in Python. There is something in the documentation I don't quite understand. In chapter 3.3 (where chunks are handled) it says:

Four bits of the type code, namely bit 5 (value 32) of each byte, are used to convey chunk properties. This choice means that a human can read off the assigned properties according to whether each letter of the type code is uppercase (bit 5 is 0) or lowercase (bit 5 is 1). However, decoders should test the properties of an unknown chunk by numerically testing the specified bits; testing whether a character is uppercase or lowercase is inefficient, and even incorrect if a locale-specific case definition is used.

Ok, so it explicitly denotes one should not test whether a byte is uppercase or lowercase. Then, how do I check that bit 5?

Furthermore, the documentation states

Ancillary bit: bit 5 of first byte
0 (uppercase) = critical, 1 (lowercase) = ancillary.

I have the following function to convert an integer to a bit-stream:

def bits(x, n):
    """ Convert an integer value *x* to a sequence of *n* bits as a string. """
    return ''.join(str([0, 1][x >> i & 1]) for i in xrange(n - 1, -1, -1))

Just for example, take the sRGB chunk. The lowercase s denotes the chunk is ancillary. But comparing the bit-streams of an uppercase S and lowercase s

01110011
01010011

we can see that bit #5 is zero in both cases.

I think I do have a wrong understanding of counting the bits. As the only bit that changes is the third one (i.e. indexed with 2), i assume this is the bit I'm searching for? It is also the 6th bit from the right and indexed with 5 (from the right of course). Is this what I'm searching for?


Solution

  • Python does have bitwise manipulation. You are doing it the hard way, when they already gave you the bitmask (32 or 0x20).

    is_critical = (type_code & 0x20) == 0
    

    or, equivalently:

    is_critical = (type_code & (0x1 << 5)) == 0
    

    (with extra parentheses for clarity)