まえがき
c#でアニメーションカーソル(.ani)ファイルを作ってみようと思ったので書いてみようと思います
ANIファイルの構造からc#での実装までをしていきます
別にc#ではなくてもよかったのですが一応c#で書いてみます
ファイル形式
RIFFファイルらしいです
名前や作成者名のチャンク、ヘッダーのチャンク、それぞれのフレームレートのチャンク、シーケンス(順番の定義)のチャンク、データのリストのチャンクでできていると思われます
数値はすべてリトルエンディアンです
実装
その構造からコードを書いていきます
出力だけを考えているので、作りやすいようにチャンクの順番は上記の通りにして作者情報はカットします
RIFFファイルのデータのサイズが奇数ならパディングしないといけないらしいのですが、面倒なので無視してみます
実装(ヘッダー)
下記の構造体は使わないですが、一応書いておきます
ヘッダーは以下のようになります
struct Anih
{
public uint HeaderSize = 36; //このサイズ
public uint DataNum; //ファイル内の含まれているアイコンデータの数
public uint FrameNum; //フレームの数
public uint Reserved1 = 0x00; //よくわからないので適当に
public uint Reserved2 = 0x00; //よくわからないので適当に
public uint Reserved3 = 0x00; //よくわからないので適当に
public uint Reserved4 = 0x00; //よくわからないので適当に
public uint Rate; //デフォルトのレート(単位に注意)
public uint Flags = 0x00000001; //定数
}
実装(RIFF)
RIFFの形式は以下のようになります
struct RiffChunk
{
public byte[] Name = new byte[4]; //ASCII文字で
public byte[] Size = new byte[4]; //Data部のサイズ
public byte[] Data;
}
struct RiffList
{
public byte[] Name = new byte[4]; //ASCII文字で
public byte[] Size = new byte[4]; //Data部のサイズ
public byte[] Format = new byte[4];
public RiffChunk[] Data;
}
実装(まとめ)
まとめると、以下のように適当に記すことが可能です
new RiffList()
{
Name = "RIFF",
Size = ファイルサイズ - 8(Name, Sizeのサイズ分),
Format = "ACON",
Data = new RiffHeader()
{
Name : "anih",
Size : 36,
Data : `new Anih() { ... }`,
},
new RiffHeader()
{
Name : "rate",
Size : フレーム数 * 4,
Data : フレームデータの配列,
},
new RiffHeader()
{
Name : "seq ",
Size : フレーム数 * 4,
Data : シーケンスデータの配列,
},
new RiffList()
{
Name = "LIST",
Size = 4 + アイコンデータ数 * 8 + アイコンデータのサイズの合計,
Format = "fram",
Data = new RiffHeader
{
Name = "icon",
Size = アイコンデータのサイズ,
Data = アイコンデータ(ファイルの中身そのままで)
},
...
},
}
おわり
ある程度のデータは使いまわし可能なので上記の構造体は無視して作っていきます
(たとえば、ヘッダーのName部やデフォルトのフレームレートなど)
長くなりすぎたのですべてのコードは以下をご覧ください
ソースコード の ToAniCursor関数です