1

我正在尝试编写一个基线 JPEG 编码器。我已经知道如何处理JFIF 格式(非常好的文章,顺便说一句)。现在我正在尝试压缩一个基本上是白色的 8x8 灰度图像。所以,考虑到一个白色像素基本上是 255,一旦你应用 JPEG 算法(避免 zig zag 步骤,因为对于这个例子它基本上是不必要的)你得到这个矩阵:

B = [63 0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0
     0  0 0 0 0 0 0 0]

正如我们所见,只有一个直流分量 (63) 而没有交流分量。如果您检查霍夫曼表,您会发现类别是 6 ( 1110 ),因为二进制中的 63 是 111111,所以这个 DC 分量的位序列是 1110111111 (10 位)。现在,根据算法,当所有AC分量都为0时,您需要发送EOB,其序列为1010(四位)。因此,最后,最终的位序列是11101111111010(14 位)。

现在,我们已经知道我只能将字节写入(或附加)到文件中。所以我想把这样的东西写到一个新的 .jpeg 文件中:

0xFF 0xD8 .. JFIF metadata ... 11101111111010 0xFF 0xD9
SOI marker                     block          EOI marker

问题是,我应该如何处理这 14 位?我想我需要插入 2 个填充位(我不知道是否有更好的术语)来获得 2 个字节,但我不知道在哪里插入它们,更不用说它们的值了(00?01?10?11 ?)。我想这是数据编码和/或低级编程中的一个常见问题,所以我得到了广泛的解决:)

4

1 回答 1

1

JPEG格式说:

唯一发生的填充是在扫描结束时,如果字节不完整,最后一个字节中的剩余位将用 1 填充。

所以你应该在1这里填写 -s 。这意味着您应该拥有:

1110       111111            1010         11
DC code    DC value (=63)    EOB (=10)    Extra 1-s

换句话说11101111 11101011,它给出了0xEF 0xEB十六进制的序列。

专业提示:您可以参考jpec中的此代码部分- 一个用 C 编写的微型 JPEG 编码器。此外,其中包括一个相关文档,可以帮助您了解如何在 Huffman 时间编写这些位。jpec_huff_write_bits

于 2013-06-03T09:24:23.617 回答