目录
一.实验目的
掌握JPEG编解码系统的基本原理。初步掌握复杂的数据压缩算法实现,并能根据理论分析需要实现所对应数据的输出。
二.实验原理
1.零偏置
将灰度级为256的图像减去256/2=128,则图像像素范围变为【-128,128】,无符号数变为有符号数。可以减小绝对值大的数字出现的概率,进而提高编码效率。
2.8×8DCT变换
将图像分为若干8×8的子块,对每一个子块进行DCT变换。
实现能量集中和去相关,去除空间冗余,提高编码效率。
3.量化
JPEG编码采取均匀量化。
4.DC系数
使用差分编码。
5.AC系数
之字形扫描+游程编码。
三.JPEG文件格式
JPEG 在文件中以 Segment 的形式组织,它具有以下特点:
- 均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);
- 采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;
- Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;
四.实验步骤
1.理解三个结构体的设计目的
- struct huffman_table:存储Huffman表,实现快速查找
struct huffman_table
{
/* 快速查找表,使用 HUFFMAN_HASH_NBITS 位我们可以直接得到符号,
* 如果符号 <0,那么我们需要查看树表 */
short int lookup[HUFFMAN_HASH_SIZE];
/* 码字长度:给出一个符号被编码的位数 */
unsigned char code_size[HUFFMAN_HASH_SIZE];
/* 存储未在查找表中编码的值的空间
* FIXME:计算256个值是否足以存储所有值 */
uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};
- struct component:定义水平和垂直采样因子和DCT系数
struct component
{
unsigned int Hfactor; /* 水平采样因子 */
unsigned int Vfactor; /* 垂直采样因子 */
float *Q_table; /* 指向要使用的量化表的指针 */
struct huffman_table *AC_table; /* 交流哈夫曼表 */
struct huffman_table *DC_table; /* 直流哈夫曼表 */
short int previous_DC; /* 前直流系数 */
short int DCT[64]; /* DCT系数 */
#if SANITY_CHECK // 调试使用
unsigned int cid;
#endif
};
- struct jdec_private:指示解码中的所有信息
struct jdec_private
{
/* 全局变量 */
uint8_t *components[COMPONENTS];
unsigned int width, height; /* 图像大小 */
unsigned int flags;
/* 私有变量 */
const unsigned char *stream_begin, *stream_end;
unsigned int stream_length;
const unsigned char *stream; /* 指向当前流的指针 */
unsigned int reservoir, nbits_in_reservoir;
struct component component_infos[COMPONENTS];
float Q_tables[COMPONENTS][64]; /* 量化表 */
struct huffman_table HTDC[HUFFMAN_TABLES]; /* 直流哈夫曼表 */
struct huffman_table HTAC[HUFFMAN_TABLES]; /* 交流哈夫曼表 */
int default_huffman_table_initialized;
int restart_interval;
int restarts_to_go; /* 在此重启间隔内剩余的 MCU */
int last_rst_marker_seen;