JPEG文件编/解码详解(3)

4.直流系数的差分编码

把所有的颜色分量单元按颜色分量(YCrCb)分类。每一种颜色分量内,相邻的两个颜色分量单元的直流变量是以差分来编码的。也就是说,通过步骤3解码出来的直流变量数值只是当前颜色分量单元的实际直流变量减去前一个颜色分量单元的实际直流变量。也就是说,当前直流变量要通过前一个颜色分量单元的实际(非解码)直流分量来校正:

DCn=DCn-1+Diff

其中Diff为差分校正变量,也就是直接解码出来的直流系数。但如果当前颜色分量单元是第一个单元,则解码出来的直流数值就是真正的直流变量。

再次提醒的是,3个颜色分量的直流变量是分开进行差分编码的。也就是说,为1张图片解码时应设置3个独立的直流校正变量。另一个问题是,当数据流中出现标记RSTn,则3个颜色分量的直流差分校正变量Diff都需要重新复位到0

 

5.反量化

不同的颜色分量使用不同的量化表,这个可以从标记段SOF中的颜色分量信息字段查得。一般是Y分量使用量化表0,而CrCb两个分量共同使用量化表1

反量化的过程比较简单。只需要对8*8的颜色分量单元的64个值逐一乘以对应的量化表内位置相同的值则可。图像内全部的颜色分量单元都要进行反量化。

 

6Zig-zag编码

如果将反量化后的每个8*8颜色分量单元的每个元素编号,如下图4,那么各反Zig-zag编码的过程就是把矩阵元素按图5重新排列。

       

图 4 将颜色分量单元元素编码                          图 5 反Zig-zag编码

 

关于量化和反Zig-zag编码的先后顺序,笔者查阅的几份资料有不同的见解。经过实践试验,解码的过程中,是应该直接用文件提供的量化表反量化矩阵数据,再将其反Zig-zag编码才能正确解码。

 

7.隔行的正负纠正

这个问题比较特别,因为在笔者认真阅读的几份资料中都没有提及此问题。而是笔者通过对已知图像进行JPEG编码压缩,然后和该图的JPEG文件数据对比发现的问题。具体原因不明。

实际上,就是必须对每个颜色分量单元的奇数行(每个颜色分量单元有8行,假设把它按01、……、67编出行号),即1357行,进行取相反数操作(正的变负,负的变正)。

 

8.反离散余弦变换

之前提到,文件中的数据是在编码时通过正向离散余弦变换(FDCT)进行时空域向频率域变换而得到的结果,所以现在解码就必须将其反向离散余弦变换(IDCT),就是把颜色分量单元矩阵中的频率域数值向时空域转换。并且,原来的频率域的矩阵大小为8*8,则经过反向离散余弦变换后,时空域的矩阵仍然是8*8

设正负纠正后的频率域矩阵为F[u][v],而反向离散余弦变换后的矩阵为f[i][j],其中0≤u,v,i,j≤7。具体使用的公式如下:

,其中

Cu(当u=0),Cu=1(当u0);

Cv(当v=0),Cu=1(当v0);

 

另外补充一下正向离散余弦变换的公式,用于编码:

 

9YCrCbRGB转换

要在屏幕上显示图像,就必须以RGB模式表示图像的颜色。所以,解码时需要把YCrCb模式向RGB模式转换。

正如前面提到,并不是每种颜色分量的采样因子都一样,所以转换时需要注意。如果采样因子是111,则每一个像素点的3个颜色分量都被采样,所以没有问题。但411的采样因子就不一样了。由“初步了解图像数据流的结构”一节中对411的采样因子的分析,可以知道一个MCU里有4Y分量单元,而Cr分量和Cb分量各自只有1个分量单元。以图2为例,仅有的一个Cr分量单元(红色的64个采样点)应该平铺用于4Y分量单元,即左上角16个值用于Y1,右上角16个值用于Y2,左下角16个值用于Y5,右下角16个值用于Y6。换句话说,一个Cr采样点服务于4Y采样点。对于Cb分量,道理一样。

另外,由于离散余弦变化要求定义域的对称,所以在编码时把RGB的数值范围从[0255]统一减去128偏移成[-128127]。因此解码时必须为每个分量加上128。具体公式如下:

R=Y                       +1.402*Cb     +128;

G=Y-0.34414*Cr    -0.71414*Cb   +128;

B=Y                       +1.772*Cb     +128;

还有一个问题,通过变换得出的RGB值可能超出了其定义域,所以要作出检查。如果大于255,则截断为255;如果小于0,则截断为0

 

下面补充RGB模式向YCrCb模式的公式:

Y =0.299*R            +0.587*G       +0.114*B    ;

Cr=   -0.1687*R      - 0.3313*G     +0.5*B  +128;

Cb=0.5 *R              - 0.4187*G     - 0.0813*B+128;

 

至此,每个MCU的解码已经完成。而每一个MCU如何组成一幅完整的图像,请参考“初步了解图像数据流的结构”分析。


参考文献

[1] 李才伟,中山大学计算机系多媒体课程教学课件.

[2]     张益贞,Visual C++实现MPEG/JPEG编解码技术.北京:人民邮电出版社

[3] CCITInformation Technology-digital Compression and Conding of Continuous-ton Still Images-requirements and Guidelineshttp://www.wotsit.org/download.asp?f=itu-1150PDF(访问日期:2007-1-1

[4] 公子御风,JFIF文件格式即JPEG文件交换格式(JPEG File Interchonge Format)http://cat1226.bokee.com/4574350.html (访问日期:2006-12-29

[5] 云风,JPEG 简易文档 V2.11http://rtornados.bokee.com/2442419.html (访问日期:2006-12-30


附录:JPEG定义的标记

标记名

标记代码

说明

帧开始标记,Start of Frame,非层次哈夫曼编码

SOF0

0xFFC0

基线离散余弦变换

SOF1

0xFFC1

扩展顺序离散余弦变换

SOF2

0xFFC2

递进离散余弦变换

SOF3

0xFFC3

空间顺序无损

帧开始标记,Start of Frame,层次哈夫曼编码

SOF5

0xFFC5

差分离散余弦变换

SOF6

0xFFC6

差分层次离散余弦变换

SOF7

0xFFC7

差分空间无损

帧开始标记,Start of Frame,非层次算术编码

JPEG

0xFFC8

为JPEG扩展保留

SOF9

0xFFC9

扩展顺序离散余弦变换

SOF10

0xFFCA

递进离散余弦变换

SOF11

0xFFCB

空间顺序无损

帧开始标记,Start of Frame,层次算术编码

SOF13

0xFFCD

差分离散余弦变换

SOF14

0xFFCE

差分层次离散余弦变换

SOF15

0xFFCF

差分空间无损

其他标记

DHT

0xFFC4

定义哈夫曼树表

DAC

0xFFCC

定义算术编码表

RST0

OxFFD0

差分编码累计复位,共8个

……

……

RST7

OxFFD7

SOI

OxFFD8

图像开始

EOI

OxFFD9

图像结束

SOS

0xFFDA

开始扫描,图像数据开始

DQT

0xFFDB

定义量化表

DNL

0xFFDC

定义线数

DRI

0xFFDD

定义差分编码累计复位的间隔

DHP

0xFFDE

定义层次级数

EXP

0xFFDF

展开参考图像

APP0

0xFFE0

为应用程序保留,共15个

……

……

APP15

0xFFEE

JPG0

0xFFF0

为JPEG扩展保留,共14个

……

……

JPG13

0xFFFD

COM

0xFFFE

注释

TEM

0xFF01

算术编码中作临时之用

RES

0xFF02

保留,共189个

……

……

RES

0xFFBF

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值