在 Cryx note关于 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 编码器/解码器 here使用我不理解的按位运算执行类别编码,我希望有人能为我澄清。 0 的 RLE 在其他地方完成,但这部分代码将剩余的像素值分解为 Cryx 文档中指定的类别。
在下面的代码中,变量code
是像素的YUV值。在 while 循环中,如果满足条件,i
就会递减,直到达到正确的类别。例如,如果像素值为 6.0,则从类别 15 开始,i
递减直至达到 3。这是通过我不理解的按位运算完成的。有人可以澄清 while 循环中正在测试什么条件吗?更具体地说, !(absc & mask)
是一个 bool 值,但我不明白这如何帮助我们了解正确的类别。
我也不清楚最后一个 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 位)数字中最有值(value)的位。运算符 &
(二进制 AND)将 absc
中除掩码为 1 的位之外的所有位清零。如果结果为零,则将掩码右移(删除最后一个二进制数字)并重复下一位。
对于值 6 = 110
b (二进制形式)while
将一直有效,直到 mask = 100
b 且 i = 2。之后 size
将设置为 3。
如果 code
为负数,最后一行会将其转换为 one’s compliment具有 size
长度的表示。您的类别列表中描述了这种负数编码。
关于c - JPEG类别编码按位运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62094171/