RIFF文件格式

1.简介


RIFF全称为资源互换文件格式(Resource Interchange File Format),是一种按照标记区块存储数据(tagged chunks)的通用文件存储格式,多用于存储音频、视频等多媒体数据。Microsoft在windows下的AVI、ANI 、WAV等都是基于RIFF实现的。

RIFF是由Microsoft和IBM于1991年,在windows 3.1中引入的,作为windows 3.1默认的多媒体文件格式。RIFF是参考Interchange File Format来的,二者主要的区别是字节序大端、小端的问题。在基于IBM的80x86系列主机下,RIFF的字节序是小端的;而在IFF原有的格式中是按照大端存储整型数据的。

RIFF文件所包含的数据类型由该文件的扩展名来标识,能以RIFF文件存储的数据包括:

  • 音频视频交错格式数据(.AVI)
  • 波形格式文件(.WAV)
  • 位图格式数据(.BMP)
  • MIDI格式文件(.RMI)
  • 调色板格式(.PAL)
  • 多媒体电影(.RMN)
  • 动画光标(.ANI)
  • 其他RIFF文件(.BND)

RIFF格式是一种树状的结构,其基本组成单元为LIST和CHUNK,分别如树的节点和叶子。RIFF格式也类似windows文件系统的组织形式,windows文件系统有目录和文件,分别对应RIFF中的LIST和CHUNK。Windows文件系统中的目录可以包含子目录和文件,而文件是保存数据的基本单元,RIFF也使用了这样的结构。在RIFF文件中,数据保存的基本单元是CHUNK,可用于保存音视频数据或者一些参数信息,LIST相当于文件系统的目录,可以包含多个CHUNK或者多个LIST。
 

2.CHUNK

RIFF文件的基本构成单元是chunk。通常情况下一个chunk是指多媒体数据的一个基本逻辑单元,比如视频的一帧数据、音频的一帧数据等等。每个chunk包含以下三个字段:

  • FOURCC(四字节码),用于标识chunk ID或chunk 类型。
  • 四字节整数,表示chunk中的数据域长度(Size)。
  • 数据域(data Field)。

chunk是可以嵌套的。
chunk是组成RIFF文件的基本单元,结构如下:

struct chunk
{
u32 id; /*块标志*/
u32 size; /*块大小*/
u8 data[size]; /*块内容*/
} 
  • id由4个ASCII字符组成,用以识别块中所包含的数据。如:'RIFF','LIST','fmt','data','WAV','AVI'等等 ,由于这种文件结构最初是由Microsoft和IBM为PC机所定义,RIFF文件是按照little-endian字节顺序写入的。 
  • size(块大小)是存储在data域中数据的长度,id与size域的大小则不包括在该值内。 
  • dat(块内容)中所包含的数据是以字(WORD)为单位排列的,如果该数据结构长度是奇数,则在最后添加一个空(NULL)字节。 

其中有仅有两种块:'RIFF'和'LIST'块可以包含其他块,而其它块仅能含有数据。

struct chunk
{
u32 id; /* 块标志 */
u32 size; /* 块大小 */
/*此时的dat = type + restdat */
u32 type ; /* 类型 */
u8 restdat[size] /* dat中除type4个字节后剩余的数据*/
};

可以看出,'RIFF'和'LIST'也是chunk,只是它的dat由两部分组成:

  • type,由4个ASCII字符组成,代表RIFF文件的类型,如'WAV','AVI ';或者'LIST'块的类型,如avi文件中的列表'hdrl','movi'。

  • restdat,dat中除type4个字节后剩余的数据,包括块内容,包含若干chunk和'LIST' 

包含在一个chunk中的chunk被称为subchunk。只有ID为“RIFF”或者“LIST”的chunk允许拥有subchunk。RIFF文件的第一个chunk的id必须是“RIFF”四字节码,也就是说id为“LIST”的chunk只能是subchunk。

“RIFF”chunk的数据域的起始位置是一个四字节码(称为Form Type,类型码),用于说明数据域的格式,比如“WAV”、“AVI”等。

“LIST”chunk的数据域的起始位置也有一个四字节码(称为List Type,类型码),用于说明LIST数据域的数据内容。比如,“LIST”chunk的list type为“INFO”时,其数据域可能包括“ICOP”、“ICRD”chunk,用于记录文件版权和创建时间信息。

2.1 FOURCC

一个FOURCC(fourcharacter code)是一个占4个字节的数据,一般表示4个ASCII字符。在RIFF文件格式中,FOURCC非常普遍,structchunk 中的id成员,'LIST','RIFF'的type成员,起始标识等信息都是用FOURCC表示的。FOURCC一般是四个字符,如'abcd'这样的形式,也可以三个字符包含一个空格,如'abc'这样的形式。

2.2 RIFF文件块

RIFF文件块的数据结构如下:

'RIFF' FileSize FileType FileData

  • 'RIFF' 是一个FOURCC,用于标识该文件是一个RIFF格式的文件。

  • FileSize 是一个4字节的数据,给出文件的大小,但仅包括FileType和FileData两部分。

  • FileType是一个FOURCC,用来说明文件类型,如"WAV","AVI"等。

  • FileData部分表示文件的具体内容,可以是LIST也可以是CHUNK.

2.3 LIST

一个LIST数据块的数据结构如下:

'LIST' ListSize ListType ListData

  • 'LIST'是一个FOURCC,而且是固定的,每个LIST都是以'LIST'为开头。

  • ListSize占用4个字节,表示ListType和ListData两部分加在一起的大小。

  • ListType是一个FOURCC,是对LIST具体包含的数据内容的标识。

  • ListData是该LIST的数据内容区,由CHUNK和子LIST组成,它们的个数和组成次序可以是不确定的。

3. 举例

4. 总结

  • RIFF文件的FileData部分由若干个'LIST'和chunk组成,而'LIST'的ListData又可以由若干个chunk和'LIST'组成,且'LIST'是可以嵌套的。

  • 'RIFF',FileType,'LIST',ListType,ChunkID都是FOURCC,即使用4字节的ASIIC字符标识类型。

  • FileSize,ListSize,ChunkSize为little-endian32-bit正整数,表示Type(只有'RIFF','LIST'chunk有Type)+Data一起的大小,注意它是little-endian表示,如:0x00123456,存储地址由低到高,在little-endian系统中的存储表示为0x56341200(字节由低位到高位存储),而在big-endian为0x00123456(字节由高位到低位存储)。

32bit整数

0x00123456

存储地址低--------->高

little-endian(字节由低位到高位存储)

56

34

12

00

big-endian(字节由高位到低位存储)

00

12

34

56

发布了26 篇原创文章 · 获赞 49 · 访问量 137万+

猜你喜欢

转载自blog.csdn.net/ldghd/article/details/89332354