JPEG压缩中ZigZag排序后AC/DC系数编码及相关技术问题咨询
一、DC系数在Huffman编码前的处理格式
你已经完成了DC系数的DPCM编码(计算当前块DC与前一块DC的差值),接下来需要将这个差值转换为**(SIZE, AMPLITUDE)**的格式(类似AC系数结构但无RUNLENGTH):
- SIZE:差值绝对值的二进制位数(例如差值为-2,绝对值是2,二进制为
10,位数为2,故SIZE=2); - AMPLITUDE:差值的二进制编码,规则为:
- 若差值为正,直接用SIZE位二进制表示该值;
- 若差值为负,用SIZE位二进制表示
(2^SIZE - |差值|)(等价于绝对值的补码)。
示例:差值为-2,SIZE=2,2^2 - 2 = 2,二进制为10,最终格式为(2, 10)(此处10为二进制位串)。
之后,SIZE部分用DC专属的Huffman表编码,AMPLITUDE部分直接以二进制位形式追加,无需Huffman编码。
二、DC系数的存储与编码组织
DC系数不是单独成块存储,而是与对应块的AC编码数据绑定,每个8x8块的编码结构为:[DC编码结果] + [AC游程编码的Huffman结果序列] + (0,0)结束标记
所有块按分量顺序(通常先Y通道从上到下、左到右,再Cb、Cr通道)依次拼接。
同时,DC和AC使用独立的Huffman表:DC有专门的DC Huffman表(亮度、色度各一张),AC有专门的AC Huffman表(亮度、色度各一张),分别对DC的SIZE和AC的(RUNLENGTH, SIZE)进行编码。
三、标准固定Huffman表的定义
JPEG标准(ITU-T T.81 / ISO/IEC 10918-1)的附录K定义了默认的固定Huffman表,分为四类:
- 亮度DC表
- 亮度AC表
- 色度DC表
- 色度AC表
以亮度DC表为例,核心定义是码长分布和对应的码字:
- 码长序列(下标为SIZE,值为对应SIZE的出现次数):
[1,1,5,1,1,1,1,1,1,1,1,1](对应SIZE 0到11) - 生成的码字:SIZE 0→
0,SIZE 1→10,SIZE 2→110/1110/11110/111110/1111110,以此类推。
亮度AC表的码长序列为[0,2,1,3,3,2,4,3,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1](下标为(RUNLENGTH, SIZE)的索引,对应0到31),再按码长生成对应的码字。
四、当前实现步骤的遗漏环节
你已完成核心的变换和预处理步骤,还缺少以下关键环节:
- DC差值的格式转换:将DPCM得到的差值转换为(SIZE, AMPLITUDE)格式,这是Huffman编码前的必要步骤;
- Huffman编码执行:使用DC/AC专属Huffman表(固定或自定义)对DC的SIZE和AC的(RUNLENGTH, SIZE)进行编码,追加AMPLITUDE的二进制位;
- JPEG文件结构封装:添加标准的JPEG标记段,包括:
- SOI(图像开始标记)
- DQT(量化表标记,写入你使用的量化表数据)
- DHT(Huffman表标记,写入固定或自定义的Huffman表)
- SOF(帧头标记,包含图像尺寸、颜色空间、采样因子等元数据)
- SOS(扫描头标记,指定编码分量、Huffman表索引等)
- 最后追加EOI(图像结束标记)
- DCT归一化处理:JPEG的正向DCT需要乘以特定的缩放因子,部分实现会将该因子合并到量化表中,若你的DCT实现未包含此步骤,会导致后续量化结果不符合标准;
- 游程编码的边界处理:确保每个块的AC游程编码都以(0,0)结束,即使该块所有AC系数均为0。
内容的提问来源于stack exchange,提问作者fafu playz

