主题:[原创]ani文件数据结构以及分解ani文件的图像的代码
一、ANI文件剖析
ANI 文件是动画光标文件,它在播放时所形成的动画效果,其实就是一幅幅的图标图像按一定的顺序绘制到屏幕上,保留指定的时间,并依序循环显示的结果。
ANI 文件也是RIFF格式文件(多媒体文件),它由“块”构成,块(包括子块)的基本结构见表1。只有标志块(RIFF-ACON)、图像信息块(anih)、数据块(LIST)的某些子块是必需的,其它块(或子块)可有可无,看情况而定。ANI 文件的常见块见表2。
表1 块的基本结构(长度单位:字节)
-------------------------------------------
偏移量 名称 长度 类型 说明
-------------------------------------------
00 块标识 4 字符 标识符的Ascii码
04 块长度 4 长整型
08 块内容 数据
-------------------------------------------
说明:
①块内容中所包含的数据是以字(WORD)为单位排列的,其长度必须为偶数,如果是奇数,则在最后添加一个空字节(NULL)。
②块长度不包括标识符4字节以及块长度项本身所占用的4字节。
表2:构成ANI文件的块
-------------------------------------
名称 字节数 说明
-------------------------------------
标志块 12 RIFF-ACON(文件头)
图像信息块 44 anih
数据块 LIST
时间控制块 rate
帧序控制块 seq
-------------------------------------
说明:
①LIST块只是一个总称,它不能独立存在,而必须由若干子块组成,换句话说,它的块内容就是各个子块的集合。常见的子块见表3。
表3:LIST块的两种常见子块
--------------------------------
子块名称 说明 备注
--------------------------------
存储块 fram
图标块 icon fram的子块
信息块 INFO
文件信息块 INAM INFO的子块
版权信息块 IART INFO的子块
--------------------------------
说明:
①LIST块的两种子块中,只有存储块是必需的,信息块可有可无。
②存储块下至少有2个图标子块,其具体数量保存在图像信息块的 cFrames 项。
表4:ANI文件头的结构(长度单位:字节)
-----------------------------------------------
偏移量 名称 长度 数据类型 内容
-----------------------------------------------
00 RIFF标志 4 字符 “RIFF”的Ascii码
04 文件长度 4 长整形 文件的总字节数
08 ANI标志 4 字符 “ACON”的Ascii码
-----------------------------------------------
说明:
①RIFF是英文Resource Interchange File Format的缩写,它是一种含有嵌套数据结构的二进制文件格式。所谓“嵌套”,是指块中有块(子块)。
②据笔者观察,有的 ani 文件的文件长度项值包括“RIFF”标志符4字节以及文件长度项本身所占用的4字节,有的不包括,笔者也不明白这是什么原因。
③为什么还要有一个“ANI标志”呢?这是因为除了动画光标(.ANI)以外,能以RIFF文件格式存储的数据还包括:音频视频交错格式(AVI)、位图格式(RDI)、MIDI格式(RMI)、调色板格式(PAL)、多媒体电影(RMN)、波形格式(.WAV)、其它RIFF文件(BND)。
表5:图像信息块的结构(长度单位:字节)
----------------------------------------------------
名称 长度 数据类型 说明
----------------------------------------------------
标识符 4 字符型 “anih”的Ascii码
块长度 4 长整形 其值为24(=10进制36)
cbSizeof 4 长整形 块长度,这个值包括项本身4字节
cFrames 4 长整形 图象帧数
cSteps 4 长整形 完成一次动画过程要显示的图象数
cx 4 长整形 图象宽度
cy 4 长整形 图象高度
cBitCount 4 长整形 颜色位数(每象素所占位数)
cPlanes 4 长整形 颜色位面板数
jifRate 4 长整形 jif速率
fl 4 长整形 AF_ICON和AF_SEQUENCE设置标记
----------------------------------------------------
说明:
①如果 fl=1,表示 AF_ICON 标记被设置,则 cFrame=cSteps,cx、cy、cBitCount、cPlanes这四项将被忽略,每一帧的 icon 都各自包含了这四项信息。
②如果 fl=2,表示 AF_SEQUENCE 标记被设置,则 cFrames<cSteps,也说明,在完成一次动画过程时,将会有图象被重复显示,ANI 文件中就必有帧序控制块。
③如果 fl=3,表示 AF_ICON 标记和 AF_SEQUENCE 标记都被设置。
④jif速率是图像显示的时间单位,1jif=1/60秒。如果有时间控制块,那么这个值不起作用。
表6:LIST-fram块的结构(长度单位:字节)
-----------------------------------------------
名称 长度 数据类型 说明
-----------------------------------------------
标识符 4 字符型 “LIST”的Ascii码
块长度 4 长整形
子块标识符 4 字符型 “fram”的Ascii码
子块标识符 4 字符型 “icon”的Ascii码
子块长度 4 长整形
子块内容 4 图像1的数据
子块标识符 4 字符型 “icon”的Ascii码
子块长度 4 长整形
子块内容 4 图像2的数据
……
-----------------------------------------------
说明:
①注意 fram 子块标识符的后面没有块长度这一项!
②图像数据实际上是一个完整的 ico 图标结构,一帧图像就是一个图标(一般都是调色板模式的图标)。
③我们在资源管理器中看见的 ani 文件的图像,是第一个 icon 子块的图像。
④关于图标的数据结构,请参阅笔者的《Ico文件数据结构》一文。
表7:时间控制块的结构(长度单位:字节)
---------------------------------------------------------
名称 长度 数据类型 说明
---------------------------------------------------------
标识符 4 字符型 “rate”的Ascii码
块长度 4 长整形 rate块的大小
块内容 块内容由若干帧显示时间项组成,要显
示的图象有几帧就有几个对应的时间项
帧显示时间 4 长整形 第一帧图像在屏幕上的显示时间
帧显示时间 4 长整形 第二帧图像在屏幕上的显示时间
……
帧显示时间 4 长整形 第N帧图像在屏幕上的显示时间
---------------------------------------------------------
说明:
①帧显示时间项的数量由图像信息块中的 cSteps 项值决定。
②帧显示时间项值表示该帧要显示几个时间单位。
③如果每幅图象的显示时间完全一样,ANI 文件就没有必要保存多个相同的时间值,而是把这个时间值保存在图像信息块的 jifRate 项里,这样,ANI 文件里就没有时间控制块。
④如果每幅图象的显示时间不一样,那就必须有时间控制块。这时,图像信息块中的 jifRate 项仍然存在,只是没有作用。
表8:帧序控制块的结构(长度单位:字节)
---------------------------------------------------------
名称 长度 数据类型 说明
---------------------------------------------------------
标识符 4 字符型 “seq ”的Ascii码
块长度 4 长整形 seq块的大小
块内容 块内容由若干帧显示序号项组成,要显
示的图象有几帧就有几个对应的序号项
帧显示序号 4 长整形 第一帧图像在屏幕上的显示序号
帧显示序号 4 长整形 第二帧图像在屏幕上的显示序号
……
帧显示序号 4 长整形 第N帧图像在屏幕上的显示序号
---------------------------------------------------------
说明:
①序号是各个图象(即icon子块)在 ANI 文件中存放的先后顺序,第一个图象的序号定义为0,第二个图象的序号定义为1,依次类推。
②显示顺序并不一定等于图象存放的先后顺序。
③如果没有帧序控制块,ANI 文件中保存的各幅图象数据均不相同,完成一次完整的动画过程要显示的图象数=文件保存的图象数。显示时,从第一幅图象开始,按文件中保存的图象的先后顺序,依次显示,一直到最后一幅图象显示完毕,然后重新从第一幅图象开始下一次的动画过程,循环往复。
④如果有帧序控制块, 说明ANI文件中的图象帧数<完成一次动画过程要显示的图象帧数(这时图像信息块中的 AF_SEQUENCE 标记应该已被设置),必定有的图像要显示的次数>1。例如一个ANI文件中有三个 icon 子块,分别为icon0、icon1、icon2,而一次完整的动画过程要显示四幅图象,其中icon1要显示两次,即:icon0-icon1-icon2-icon1,在这种情况下,ANI文件没有必要把 icon1 的数据保存两次,而只是保存一次,但增加了帧序控制块,在帧序控制块中保存了完成一次完整的动画过程所要显示的图象的序号,这样就有效地减小了文件的大小,避免了冗余数据的保存和处理。
表9:LIST-INFO块的结构(长度单位:字节)
---------------------------------------------------------
名称 长度 数据类型 说明
---------------------------------------------------------
标识符 4 字符型 “LIST”的Ascii码
块长度 4 长整形
子块标识符 4 字符型 “INFO”的Ascii码,信息子块
子块标识符 4 字符型 “INAM”的Ascii码,文件信息块
子块长度 4 长整形
子块内容 4 字符型 INAM块的内容
子块标识符 4 字符型 “IART”的Ascii码,版权信息块
子块长度 4 长整形
子块内容 4 字符型 IART块的内容
---------------------------------------------------------
说明:
①注意 INFO 子块标识符的后面没有块长度这一项!
②INFO 子块又有2个子块:文件信息块、版权信息块。