Код типа блока PNG Бит # 5

Я пытаюсь написать свою собственную маленькую программу для чтения PNG на Python. В документации есть что-то, что мне не совсем понятно. понимать. В главе 3.3 (где обрабатываются фрагменты) говорится:

Четыре бита кода типа, а именно бит 5 (значение 32) каждого байта, используются для передачи свойств фрагмента. Этот выбор означает, что человек может считывать назначенные свойства в соответствии с тем, является ли каждая буква кода типа прописной (бит 5 равен 0) или строчной (бит 5 равен 1). Однако декодеры должны проверять свойства неизвестного фрагмента, численно проверяя указанные биты; проверка того, является ли символ прописным или строчным, неэффективна и даже неверна, если используется определение регистра для конкретной локали.

Итак, это явно означает, что не следует не проверять, является ли байт прописным или строчным. Тогда как мне проверить этот бит 5?

Кроме того, в документации указано

Вспомогательный бит: бит 5 первого байта
0 (верхний регистр) = критический, 1 (нижний регистр) = вспомогательный.

У меня есть следующая функция для преобразования целого числа в битовый поток:

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))

Для примера возьмем чанк sRGB. s в нижнем регистре означает, что фрагмент является вспомогательным. Но сравнивая битовые потоки прописных S и строчных s

01110011
01010011

мы можем видеть, что бит № 5 равен нулю в обоих случаях.

Я думаю, что у меня неправильное понимание подсчета битов. Поскольку единственный бит, который меняется, - это третий (т.е. индексированный с 2), я предполагаю, что это тот бит, который я ищу? Это также 6-й бит справа и индексируется с помощью 5 (конечно, справа). Это то, что я ищу?


person Niklas R    schedule 09.06.2012    source источник
comment
На случай, если вы сочтете это полезным, я написал программу чтения/записи PNG (полную, за исключением чересстрочной развертки) на Java с открытым исходным кодом: code.google.com/p/pngj   -  person leonbloy    schedule 11.06.2012


Ответы (1)


В Python есть побитовые манипуляции. Вы делаете это трудным путем, когда вам уже дали битовую маску (32 или 0x20).

is_critical = (type_code & 0x20) == 0

или, что то же самое:

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

(с дополнительными скобками для ясности)

person msw    schedule 09.06.2012
comment
Ха, я не думал об этом xD Спасибо. Кстати, это не шестигранник 32 0x20? - person Niklas R; 09.06.2012