在有关JPEG压缩的Cryx note中,类别被描述为“我们可以保留该值的位的最小大小”。继续说,落入一定范围内的值被归类。我在下面粘贴了一部分,但没有粘贴整个表格。
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编码器/解码器here使用我不了解的按位运算来执行类别编码,我希望有人可以为我澄清。 RLE的0在其他地方完成,但是代码的这一部分将剩余的像素值分解为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
中的所有位清零,掩码中的一位除外。如果结果为零,则向右移掩码,并与下一位重复。
对于值6 =110
b(二进制形式),while
将起作用,直到掩码=100
b并且i =2。之后,size
将被设置为3。
如果code
为负,则最后一行将以one’s compliment长度将其转换为size
表示形式。结果如表中所述。