Ani动态光标格式解析

数据结构

Ani文件中的数据是按区段存放的,区段数据结构如下:

标识符(4字节ASCII),数据长度(一个DWORD),数据

按照此规则来看Ani文件,文件起始12字节可以理解为标准文件头,除数据长度外,其余两个字段不会改变:

0x0000    52 49 46 46    标识符'RIFF'
0x0004    40 4D 00 00    数据长度
0x0008    41 43 4F 4E    'ACON'

标准头之后,就是各个区段了,在我的探索中共发现了:'anih', 'rate', 'seq ', 'LIST'4种区段('seq '区段标识最后一个字符是空格,共4个字符)。

'anih'

此区段数据长度恒为36,里面存储的是一个结构体:

struct _anih
{
    DWORD    dwHeaderSize;     //结构体大小
    DWORD    dwNumFrames;      //图像帧数
    DWORD    dwNumSteps;       //播放帧数,当'seq '存在时可能大于dwNumFrames
    DWORD    dwWidth;          //图像宽度
    DWORD    dwHeight;         //图像高度
    DWORD    dwBitCount;       //色彩位数
    DWORD    dwNumPlanes;      //设备平面数
    DWORD    dwDisplayRate;    //显示频率(Time Delay,单位为1/60秒)
    DWORD    dwFlags;          //标志
};

dwFlags的第0位为1时,表示图像帧数据格式为Icon或Cursor,为0表示图像帧数据为位图raw数据,使用_anih结构中的尺寸、色彩深度等信息。

第1位解释为bool型,表示文件是否含有'seq '段。

'seq '

此区段为可选段(不一定存在),段内的数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

0x0000    73 65 71 20    标识符'seq '
0x0004    24 00 00 00    数据长度
0x0008    00 00 00 00    数组元素[0],值为0表示此处显示第0帧图像
0x000C    01 00 00 00    数组元素[1],值为1表示第一帧图像
0x0010    02 00 00 00    [2],第2帧
0x0014    03 00 00 00    [3],第3帧
0x0018    00 00 00 00    [4],第0帧
0x001C    04 00 00 00    ...
0x0020    05 00 00 00
0x0024    01 00 00 00
0x0028    00 00 00 00

此区段存储的是播放顺序,当Ani文件播放时,按照DWORD数组下标递增,依次从此数组中取出图像帧号,再到存储图像帧数据的'LIST'段中获取对应的图像帧进行显示。所以在一次播放中,同一个图像帧可以出现多次。_anih结构中的dwNumSteps即为播放起始数组下标。

此区段不存在时,'LIST'中图像帧的顺序即为播放顺序,_anih结构中的dwNumSteps为播放起始帧号。

'rate'

此区段为可选段,段内数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

0x0000    72 61 74 65    标识符'rate'
0x0004    24 00 00 00    数据长度
0x0008    0F 00 00 00    x 1/60秒 = Time Delay
0x000C    0F 00 00 00
0x0010    0F 00 00 00
0x0014    0F 00 00 00
0x0018    46 00 00 00
0x001C    0F 00 00 00
0x0020    0F 00 00 00
0x0024    0F 00 00 00
0x0028    0F 00 00 00

此区段内存储的为播放频率(Time Delay),同样以1/60秒为单位,当'seq '存在时,按相同下标与'seq '中的每个元素相对应,数组大小与'seq '相等。当'seq '不存在时,与'LIST'中图像帧相对应,数组大小等于_anih结构中的dwNumFrames。

'LIST'

同样拥有12字节“标准头”,探索中发现,此区段内存储的数据有两种可能:

1.Ani文件的名称、作者

2.图像帧数据

当存储名称、作者信息时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    26 00 00 00    数据长度
0x0008    49 4E 46 4F    标识符'INFO'表示此列表为信息列表

0x000C    49 4E 41 4D    标识符'INAM'表示名称
0x0010    0C 00 00 00    数据长度
0x0014    68 65 61 72 74 73 74 69 63 6B 31 00    字符串'heartstick1'

0x0020    49 41 52 54    标识符'IART'表示作者
0x0024    06 00 00 00    数据长度
0x0028    68 75 61 6C 69 00    字符串'huali'

当存储图像帧数据时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    90 11 00 00    数据长度
0x0008    66 72 61 6D    标识符'fram'表明此列表为图像数据帧列表

0x000C    69 63 6F 6E    标识符'icon'标识图像数据帧数据区段
0x0010    BE 08 00 00    数据长度
0x0014    00 00 02 00    图像数据
...       ...            多帧图像

至此,数据结构解析完毕。

原文地址:https://www.cnblogs.com/youlin/p/3282263.html