当前位置:[北京同好会]>[观测设备]>[20D]>[CR2 RAW文件(二)图像解码]

 

CANON CR2 RAW文件(二)图像解码

通过读DCRAW(http://www.cybercom.net/~dcoffin/index.html)源程序学到了许多东西。终于搞明白了CR2的结构。

下面的一些术语可能用得不甚准确,只是用来描述编程的思路。

RAW图像偏置值可以定位到RAW图像数据块的起始点。

以下双字节整型高位字节在前,低位字节在后。

第一个是整数0xFFD8。

接下来的信息块类似IFD,包含多个组,每个数据块组结构是:

第一个2字节的整数为tag,表示是哪种信息
第二个2字节的整数为len,表示以字节为单位的数据长度,包括本整数。
接下来是len字节长的数据。

tag(hex)
len
说明
FFC3
12
2-5字节为2个双字节整数,第一个是存储图像高度,第二个是存储图像的宽度的一半
FFC4
60
解码表
FFDA
8
CCD压缩数据的开始

解码表是60个单字节的数组,1-30字节为奇数列(1,3,5……)的解码表,31-60字节是偶数列(2,4,6……)的解码表。

30字节的编解码表结构:

1:0用于奇数列,1用于偶数列。

2-17:按照顺序分别代表从1到16位码字的数量,其和为13,即共有13种码字。

18-30:每种码字后面对应的数据比特数。

码字的确定:

定义'最大码字'。(最大码字并非真正的码字)

设:‘0'位数的最大码字是0。

如果某个位数的最大码字是N,则下一个位数的最大码字为2*N+M,M是下一个位数的码字的数量。

下一个位数的码字从2*N开始依次增加,直到2*N+M-1。数量M分别由编码表中2-17字节对应的数值确定。

解码树:

按照以上编码表构造出2个二叉解码树,分用于奇偶列。

解码树可以用链表来实现。对每一个码字,从根节点出发,测试每一位对应的节点,如果不存在,则创建节点。最后一位对应的节点存储数据比特数。

解压缩:

从FFDA开始是真正的CCD数据,按行的顺序排列,采用变长压缩形式,注意每个0xFF后面的一个字节被忽略。

每个像元的数据格式是码字+数据。由码字确定数据的长度,即比特数,进而读出数值。如果此数的最高位是0,则表示是负值,需要取补码。

例如,假设码字010对应的比特数是7,则以下比特列 0100010100100…… 解码过程是:

1)读010,解析出数据长度7比特

2)读7个比特:0010100 |b=20

3)最高位是0,实际数值是 20-1111111|b=-107

这样读出的每个像元位置上的数值还不是原始数据,而是经过了变换。恢复的步骤是:

1)第1行第1、2个数值分别加2048

2)第1、2列从第2行起,依次每个像元的值加上上一行同列像元的值

3)从第3列起,依次每个像元的值加上左边第2列同行像元的值

这样就获得了CCD的原始感光数据。20D的CFA排列方式是:

RGRGRGRG
GBGBGBGB

由此加上色彩均衡,即得到彩色图像。

2005-4-16