C JPEG类别按位编码操作

C JPEG类别按位编码操作,c,jpeg,C,Jpeg,在关于JPEG压缩的Cryx中,类别被描述为“我们可以保持该值的最小位大小”。它接着说,在一定范围内的值被分类。我在下面贴了一段,但不是整张桌子 Values Category Bits for the value 0 0 - -1,1 1 0,1 -3,-2,2,3

在关于JPEG压缩的Cryx中,类别被描述为“我们可以保持该值的最小位大小”。它接着说,在一定范围内的值被分类。我在下面贴了一段,但不是整张桌子

     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编码器/解码器使用我不理解的按位操作执行类别编码,我希望有人能为我澄清。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;
unsigned absc=abs(*code);
无符号掩码=(1>=1;i--;}
*尺寸=i+1;

如果(*code<0)*code=(1
,而
此处用于查找
code
中的最高有效位。或者换句话说,
code
的长度(以位为单位)

因此,循环应用掩码来获取
code
中的下一位。首先,掩码是二进制形式的
10000000000000
,第15位为
1
(从零开始),最大值位为2字节(16位)数。运算符
&
(二进制和)将
absc
中的所有位归零,掩码中有1位的位除外。如果结果为零,则向右移位掩码(删除最后一个二进制数字),并用下一位重复

对于值6=
110
b(二进制形式)
,而
将一直工作到掩码=
100
b和i=2。之后
大小将设置为3


如果
code
是负数,那么最后一行将以
size
长度表示它。负数的这种编码在您的类别列表中有描述。

非常感谢,这是一个很好的答案。您能详细说明一下如何使用右位移位来找到正确的类别吗?@m_ridge right shift运算符
>>=1
将所有位移动一位位置至“右侧”-至最低有效位。更多图片信息:。例如,
1000
b在右移一位位置后将转换为
100
b。在我们的情况下,掩码将在每个循环步骤上更改,并测试下一位位置中的1。当找到1时,我们退出循环。如果答案有帮助,请随意向上投票l、 你甚至可以在接受的答案上这样做。哦,我想我明白了。例如,如果31是
11111
b,掩码是
100000
I
将递减,然后
mask
变为
10000
,此时
将显示最右边的位有一个1,即
!(absc&mask)
=1和
while
停止感谢您的帮助,非常感谢!