JPEG 类别编码按位运算

JPEG category encode bitwise operation

在关于JPEG压缩的Cryxnote中,类别描述为"the minimum size in bits in which we can keep that value"。它接着说,落在特定范围内的值被归类。我在下面粘贴了一段但不是整个 table。

     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 

发现 here 的 JPEG encoder/decoder 使用我不理解的按位运算执行类别编码,我希望有人能为我澄清。 0 的 RLE 在别处完成,但这部分代码将剩余的像素值分解为 Cryx 文档中指定的类别。

在下面的代码中,变量code是像素点的YUV值。在while循环中,如果满足条件,则i递减,直到到达正确的类别。比如像素值为6.0,从类别15开始,i递减,直到达到3。这是通过我不理解的按位运算完成的。有人可以澄清 while 循环中正在测试什么条件吗?更具体地说,!(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;
这里的

while用来查找code中的最高位。或者换句话说 - code 的长度(以位为单位)。

循环随后应用掩码以获取 code 中的下一位。首先,掩码是 1000000000000000 的二进制形式,第 15 位(从零开始)是 1,这是 2 字节(16 位)数字中最有价值的位。运算符 &(二进制与)将 absc 中的所有位清零,但掩码中的 1 除外。如果结果为零,则将掩码右移(删除最后一个二进制数字)并重复下一位。

For value 6 = 110b (binary form) while will work til mask = 100b and i = 2. 之后 size 将被设置到 3.

如果 code 为负数,则最后一行会将其转换为 one’s compliment 表示形式,长度为 size。您的类别列表中描述了这种负数编码。