JPEG文件解析

JPEG文件结构框架

整个JPEG包含了三个结构体,分为了三个层次:帧、MCU、和存放DC、AC系数的霍夫曼码表。
struct huffman_table:

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];
  };

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;//指向AC系数的Huffman表
  struct huffman_table *DC_table;//指向DC系数的Huffman表
  short int previous_DC;    /* Previous DC coefficient */
  short int DCT[64];        /* DCT coef */
#if SANITY_CHECK
  unsigned int cid;
#endif
};

struct jdec_private:
JPEG文件解析_第1张图片
由于贴代码网页经常崩溃,后面都使用截图。

TRACE的使用

在程序中想要独立于程序之外做一些修改可以使用
#if TRACE
#end if
这样当difineTRACE为1的时候则启动

解码后输出YUV文件

将write_YUV修改即可
JPEG文件解析_第2张图片

输出量化矩阵和霍夫曼码表

量化矩阵经过build_quantization_table函数计算,通过标准量化表与缩放因子相乘获得。
量化矩阵的之字形扫描方法是剪了一个64字节的之字形扫描顺序的结构体zigzag,由此来确定顺序。

JPEG文件解析_第3张图片
我们可以在程序解析量化矩阵时输出量化矩阵,也就是在parse_DQT函数中加上输出语句:
JPEG文件解析_第4张图片
霍夫曼码表原程序已经有了输出,我们只需要改一下main函数中解析jpg文件的函数,只解析一次就可得到输出。
JPEG文件解析_第5张图片
JPEG文件解析_第6张图片

DC图像分布与AC图像分布

首先创建DC文件于AC文件指针,在tinyjpeg_decoding这个函数中,每循环一个块计算一个DC于AC值,并存入文件。最后再将YUV的末尾补上128的色度值。
JPEG文件解析_第7张图片
JPEG文件解析_第8张图片
这其中由于DC系数很大,变化范围为-512~512,因此为了显示进行变换,而AC系数也为了显示抬高128.
输出的图像有DC、AC的第一个系数和第三个系数。
JPEG文件解析_第9张图片
JPEG文件解析_第10张图片
JPEG文件解析_第11张图片
可以看出DC系数是包含了图像的主要信息,而到了AC的第三个系数几乎没有什么变化了,包含了很少的信息。
对于几个图像做概率分布统计。
JPEG文件解析_第12张图片
JPEG文件解析_第13张图片

JPEG文件解析_第14张图片
可见DC系数不符合拉普拉斯分布,而AC系数几乎符合拉普拉斯分布,因此这也解释了为什么对于dc系数要进行差分编码再进行霍夫曼编码,而ac系数可以直接进行霍夫曼编码。

你可能感兴趣的:(JPEG文件解析)