JPEG解码详解--实例

根据前面学习到的jpeg解码知识,编写jpeg解码code,此处采用实际的解码过程对jpeg进行讲解

如图1,为实际的jpg图像数据,根据JPEG格式,解析出对应的标识符与对应的数据信息。

JPEG解码详解--实例_第1张图片

FF D8:SOI    文件头

FF E0:APP0 图像信息识别

FF DB:DQT  量化表

FF C0:SOF0 帧开始

FF C4:DHT   Huffman表

FF DA:SOS  扫描行开始

encode数据

FF D9:SOI   文件尾

扫描文件头,得到有效的DQT量化表信息,如图1:

JPEG解码详解--实例_第2张图片

SOF识别图像基本信息,如图2:

 图像分辨率:1920*1080,解码4:1:1图像,y分量是Cb、Cr的4倍;

MCU大小为8*8,4:1:1模式下,1920/(8*2)=120,1080/(2*8)=67.5,此时需要补偿整数个MCU,所以实际宽为68*16=1088,共有120行,68列个MCU。

所以,实际处理的图像大小为1920*1088,120*68个MCU,每个MCU大小是8*8,Y分量按照2*2个MCU解码。

DHT Huffman表信息,并根据 JPEG中Huffman解码实例讲解 ,重建Huffman树,得到Huffman的code与size表, 如图3,00 -> Y-DC,tablenum=0:

JPEG解码详解--实例_第3张图片

图4,10 -> Y-AC,tablenum=1:

JPEG解码详解--实例_第4张图片

图5,01 -> CbCr-DC,tablenum=2:

JPEG解码详解--实例_第5张图片

图6,11 -> CbCr-AC,tablenum=3:

JPEG解码详解--实例_第6张图片

SOS之后,3byte数据省略(用作他途),后续即可读取有效的32bit数据,解码如下:

JPEG解码详解--实例_第7张图片

获取32bit数据:0xe2e8a28a --> 1110 0010 1110 1000 1010 0010 1000 1010

Huffman查表得到DHT码字:0x06,高4bit表示零保留位数,低4bit表示数据位长,即取接下来6bit数据;

取得6bit数据:0010 11 ==>0xb

计算实际的数据值:(0xb+1)-(1<<6) = -52,累计使用的bit数量为10 bit

DC数据经过DPCM编码。即当前DC值减去前一个DC值的结果,MCU首个DC值必为0,所以DC值为得出的数据+DC数据,此时DC量化后的实际值为-52;(AC数据不需要做DPCM编码)

量化:用像素值÷量化表对应值所得的结果

所以,逆量化数据值=DQT*(-52),此时得到-416;

对逆量化数据做反Zig-Zag,得到-416;

 反Zig-Zag表:

0 1 8 16 9 2 3 10
17 24 32 25 18 11 4 5
12 19 26 33 40 48 41 34
27 20 13 6 7 14 21 28
35 42 49 56 57 50 43 36
29 22 15 23 30 37 44 51
58 59 52 45 38 31 39 46
53 60 61 54 47 55 62

JPEG解码详解--实例_第8张图片

原图像是分割为8*8的MCU块单独编码,所以解码也是按照一个MCU来解码。

当一个MCU解码时:

1. DC分量遇到数据位长为0时,数据也为0;

2. AC分量遇到EOB结束符号时,结束该MCU解码:零保留个数为0,数据位长也为0时;

3. AC分量遇到ZRL码时,是为15个零数据:零保留个数为0xF,数据位长为0时;

最终解码出来的MCU的DCT数据为:

JPEG解码详解--实例_第9张图片

将DCT数据做反DCT变化,得到实际的YUV像素数据:

JPEG解码详解--实例_第10张图片

将YUV数据转换为RGB格式,保存为可视bmp格式。

 R = (u8_t)(Y+ 1.4075*(Cr - 128));  
 G = (u8_t)(Y-0.7169*(Cr - 128)-0.3455*(Cb - 128));  
 B = (u8_t)(Y+1.779*(Cb- 128)); 

 

你可能感兴趣的:(JPEG解码,JPEG)