数据压缩作业:JPEG原理分析及JPEG解码器的调试

本文详述了JPEG编解码原理,包括JPEG文件格式的组成,如APPn、DQT、DHT标记段。重点讨论了解码流程,如零偏置、8*8DCT变换、量化、DC和AC系数处理。并通过代码解析和实验结果展示,解释了JPEG解码的具体实现,包括Huffman码表的解析和解码过程。
摘要由CSDN通过智能技术生成

JPEG 是Joint Photographic Experts Group(联合图像专家小组)的缩写,是第一个国际图像压缩标准。JPEG图像压缩算法能够在提供良好的压缩性能的同时,具有比较好的重建质量,被广泛应用于图像、视频处理领域。人们日常碰到的".jpeg"、''.jpg"等指代的是用JPEG算法压缩出来的静态图片文件在媒体上的封存形式,不能与JPEG压缩标准混为一谈。 

一、实验内容

1、JPEG编解码原理

JPEG编码的过程如上图所示。解码是编码的逆过程。 

2、JPEG文件格式

JPEG 在文件中以 Segment 的形式组织,它具有以下特点:

1.均以 0xFF 开始,即表示图像开始SOI (Start of Image)标记,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);

2.采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;

3.Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;

4.一定以0xFFD9结束,表示图像结束EOI(End of Image)标记

(1)APPn,数值0xFF E1~0xFFEF
*N=1~15,数值对应0xE1~0xEF
*APPn长度(Length)
*应用细节信息(Application specific information)
*EXIF文件格式中多写入0xFF E1

(2)DQT标记段,包括一个或者多个量化表
*量化表长度。长度参数占用两个字节,他不包括前两个字节0XFF和0XDB。
*量化表数目。表数目参数占用一个字节,其中高4位为量化表的数据精确度。若高4位等于0,那么后面的量化表中的每个值占8位;若高4位等于1,那么后面的量化表中每个值占16位,低4位表示量化表的编号,为0~3.
*量化表表项。表项参数对应Z字形排列后的64个数值。

(3)DHT标记段,包括一个或多个霍夫曼表
*霍夫曼码表的长度。占用两个字节。
*每个霍夫曼码表(霍夫曼码表一般不止一个,但是绝对不多于4个)都包含4个信息:索引、类型、位表和内容编码。索引信息表示该霍夫曼表的表号,占1个字节。高四位可以是0或1,为0时指DC所用的霍夫曼表;为1时,指AC所用的霍夫曼表。低4位表示霍夫曼表的编号,值为0或1.位表是一个长为16字节的编码,其代码代数和为接下来的编码长度。内容编码信息表示每个霍夫曼码字对应的值

 3、JPEG 的解码流程

 (1)零偏置(level offset)

对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数

对于n=8,即将0~255的值域,通过减去128,转换为值域在-128~127之间的值

目的:使像素的绝对值出现3位10进制的概率大大减少

(2)8*8DCT变换

对每个单独的彩色图像分量,把整个分量图像分成8×8的图像块,若边缘未满8*8,则用边缘像素进行填充(不建议用黑或白像素填充的原因是可能会破坏图像的原有结构)。

DCT变换使用下式计算:

 图像的低频部分集中在每个8*8块的左上角,高频部分集中在右下角。

(3)量化

因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:亮度量化值和色差量化值;根据人眼的视觉特性(对低频敏感,对高频不太敏感)对低频分量采取较的量化,对高频分量采取较的量化。

(4)DC系数

8×8图像块经过DCT变换之后得到的DC直流系数有两个特点:系数的数值比较大 ,相邻8×8图像块的DC系数值变化不大——有冗余;对此,JPEG算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化DC系数的差值DIFF进行编码。

(5)AC系数

由于经过DCT变换后,系数大多集中在左上角,也就是低频分量区,因此采用Z字形扫描,按频率的高低顺序读出,这样会出现很多的连零,可以使用RLE游程编码,尤其是在最后,如果都是零,直接给出EOB(End of Block)即可
在JPEG编码中,游程编码的形式为:(run,level)
表示连续run个0后有值为level的系数
run最多15个,用4位表示RRRR
level,类似DC,
        分成16个类别,用4位SSSS表示类别号,
        类内索引
对(RRRR,SSSS)采用Huffman编码,
对类内索引采用定长编码

二、实验步骤

(1)实验用图:

SOI和EOI

  

(2)代码结构体分析

  • 结构体struct  huffman_table——存储Huffman码表
struct huffman_table
{
  /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
   * if the symbol is <0, then we need to look into the tree table */
  short int lookup[HUFFMAN_HASH_SIZE];       //获取权值对应的码字
  /* code size: give the number of bits of a symbol is encoded */
  unsigned char code_size[HUFFMAN_HASH_SIZE];   //获取权值对应的码长
  /* some place to store value that is not encoded in the lookup table 
   * FIXME: Calculate if 256 value is enough to store all values
   */
  uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];    //当码长>9时,交给该表处理
};
  • 结构体struct  component——存储当前像块中关于解码的信息
    struct component 
    {
      unsigned int Hfactor;
      unsigned int Vfactor;
      float *Q_table;		/* Pointer to the quantisation table to use */
      struct huffman_table *AC_table;
      struct huffman_table *DC_table;
      short int previous_DC;	/* Previous DC coefficient */
      short int DCT[64];		/* DCT coef */
    #if SANITY_CHECK
      unsigned int cid;
    #endif
    };
    
  • 结构体struct  jdec_private——存储图像宽高、码表等信息
struct jdec_private
{
  /* Public variables */
  uint8_t *components[COMPONENTS];
  unsigned int width, height;	/* Size of the image */
  unsigned int flags;

  /* Private variables */
  const unsigned char *stream_begin, *stream_end;
  unsigned int stream_length;

  const unsigned char *stream;	/* Pointer to the current stream */
  unsigned int reservoir,
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值