c - JPEG类别编码按位运算

标签 c jpeg

在 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 = 110b (二进制形式)while 将一直有效,直到 mask = 100b 且 i = 2。之后 size 将设置为 3。

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

关于c - JPEG类别编码按位运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62094171/

相关文章:

c++ - 如何在程序中不使用分号的情况下打印分号(;)?

c - 在 C 程序中处理 Sqlite3 CORRUPT 错误 (11) 的更好方法是什么?

r - 在 R 中保存 png() 和 jpeg() 结果不一致

image - 如何将 []byte 对象转换为图像并将其作为 jpeg 图像存储在磁盘上

java - JPEG 格式的原始数据 - JAVA

pdf - 使用 ImageMagick 和/或 GhostScript 将多页 PDF 转换为多个 JPG

c - 在C套接字上设置VLAN,在另一端接收

c - OpenGL 着色器编译代码位于何处?

php - Imagecreatefromwebp() : WebP decode: fail to decode input data

c - gethostbyname() 或 getnameinfo() 如何在后台工作?