Категория JPEG кодирует побитовую операцию - PullRequest
2 голосов
/ 29 мая 2020

В примечании Cryx о сжатии JPEG категории описаны как «минимальный размер в битах, в котором мы можем сохранить это значение». Далее говорится, что значения, попадающие в определенные диапазоны, помещаются в категории. Я вставил сегмент ниже, но не всю таблицу.

     Values             Category        Bits for the value

    0                   0                   -

      -1,1                  1                  0,1

   -3,-2,2,3                2              00,01,10,11

 -7,-6,-5,-4,4,5,6,7            3    000,001,010,011,100,101,110,111 

Кодировщик / декодер JPEG, найденный здесь , выполняет кодирование категорий с помощью побитовой операции, которую я не понимаю, и я надеюсь, что кто-то сможет уточнить для меня. RLE из 0 выполняется в другом месте, но эта часть кода разбивает оставшиеся значения пикселей на категории, как указано в документе Cryx.

В приведенном ниже коде переменная code представляет собой значение YUV-значения пикселя. В то время как l oop, если условия выполняются, i уменьшается до тех пор, пока не будет достигнута правильная категория. Например, если значение пикселя равно 6.0, начиная с категории 15, i уменьшается до достижения 3. Это делается с помощью поразрядной операции, которую я не понимаю. Может кто-нибудь уточнить, какое состояние сейчас проверяется l oop? В частности, !(absc & mask) является логическим значением, но я не понимаю, как это помогает нам определить правильную категорию.

Причина последнего оператора if мне также не ясна. Спасибо

    unsigned absc = abs(*code);
    unsigned mask = (1 << 15);
    int i    = 15;
    if (absc == 0) { *size = 0; return; }
    while (i && !(absc & mask)) { mask >>= 1; i--; }
    *size = i + 1;
    if (*code < 0) *code = (1 << *size) - absc - 1;

1 Ответ

2 голосов
/ 30 мая 2020

while здесь используется для поиска самого старшего бита в code. Или другими словами - длина code в битах.

l oop, следовательно, применяет маску для получения следующего бита в code. Во-первых, маска имеет вид 1000000000000000 в двоичной форме с 1 в 15-м бите (отсчитывается от нуля), бит с наибольшим значением в 2-байтовом (16-битном) числе. Оператор & (двоичное И) обнуляет все биты в absc, кроме одного с 1 в маске. Если результат равен нулю, чем маска сдвига вправо (удалите последний двоичный di git) и повторите со следующим битом.

Для значения 6 = 110 b (двоичная форма) while будет работать до маски = 100 b и i = 2. После этого size будет установлено в 3.

Если code было отрицательным, то последняя строка преобразует его в комплимент представление с size длина. Такая кодировка отрицательных чисел описана в вашем списке категорий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...