DSFファイル3

前回に引き続き、ID3v2 ヘッダの料理に入る。
今回はドキュメントを参照してヘッダの定義をC言語の構造体で定義し、
次回、この定義を使って実際にID3v2ヘッダを読んでみる。

http://id3.org/id3v2.4.0-structure から抜粋

[全体の構造]
     +-----------------------------+
     |      Header (10 bytes)      |
     +-----------------------------+
     |       Extended Header       |
     | (variable length, OPTIONAL) |
     +-----------------------------+
     |   Frames (variable length)  |
     +-----------------------------+
     |           Padding           |
     | (variable length, OPTIONAL) |
     +-----------------------------+
     | Footer (10 bytes, OPTIONAL) |
     +-----------------------------+
struct meta_chunk {
	//ID3v2 ファイル識別子 'I' 'D' '3'の文字列 
	char name[3];

	/* ID3v2バージョン
		はじめの1バイトは、メジャーバージョンを示し、2バイト目は改訂番号を示す。
		メジャーバージョンに変化がなければ、改訂番号が変わっても古いバージョンとの互換性は保たれる。
		例えば。メジャーバージョンが 3 で改訂番号が 0 の場合は、ID3v2.3.0となり、
		もしソフトウエアがID3v2.2.0かそれ以下のバージョンのタグしかサポートしていなくて、
		ID3v2.3.0かそれ以上のバージョンのタグに出会った場合、すべてのタグを無視するべきである。
		メジャーバージョンと改訂番号は 0xFFになることはない。
	*/
	char version[2];

	/* ID3v2フラグ 1バイト 現在は3つのフラグ情報が格納されている
		a - 非同期化
			「ID3v2フラグ」の第7ビットは、非同期化が行われているかを示している(詳細はセクション5を参照のこと)。
			このビットが1である場合は、非同期化が行われている。
		b - 拡張ヘッダ
			左から2番目のビット(第6ビット)はヘッダの後に拡張ヘッダがつけられているかを示す。
			拡張ヘッダについてはセクション3.2で解説されている。
		c - 実験中
			左から3番目のビット(第5ビット)は「実験中」を示す識別子として使用される。
			このフラグが立っている場合、そのタグが現在実験段階にあることを示している。

	  これ以外のフラグビットはすべて0にしておくべきである。
	  もし認識できないフラグがセットされていた場合は、そのフラグの機能が不明であるため、
	  タグ全体が読み込み不可能である可能性のあることを意味する。
	*/
	unsigned char flag;//ID3v2 フラグ %abc00000

	/* ID3v2タグサイズ 4バイト
		最重要(第7ビット)がすべて0になるようにエンコードされた4バイトのデータであり、
		全部で28ビットのデータである。0にセットしたビットは無視する。
		したがってタグのサイズが257バイトであった場合は、00 00 02 01と表現される。

		ID3v2タグサイズには、非同期化処理を終えた後のタグ全体のサイズを格納する。
		Padding領域と拡張ヘッダ領域は含めるが、ヘッダ領域は含めない(総タグサイズ-10ということになる)。
		サイズ情報として使えるのは28ビットであるので、「偽の同期信号」を含まないようにした最大256メガバイトまでの
		ヘッダを使うことができる
	*/
	union {
		unsigned char data[4];
		long l;
	} size;

};

//ID3v2 フレーム
//タグ中には少なくとも一つ以上のフレームが無くてはならず、
//フレームには、ヘッダ以外に少なくとも1バイトのデータが無くてはならない
struct meta_frame {
	unsigned char id[4];// 4byte. フレーム IDは0-9と大文字のA-Zで構成されている。
						//「X」、「Y」、「Z」で始まるIDは、タグヘッダに「実験中」のフラグを立てなくても、実験的に用いたり、
						// 自由に定義して用いることができる。ただし、他の誰かが同じIDを別の意味に使う可能性もあることを忘れないようにしなくてはならない。それ以外のIDは、現在使われていないものでも将来の拡張のために予約されている。

	unsigned char size[4];	//すべてのフレームにおいて、フレームヘッダのサイズは10バイトに固定されており、
							//サイズ情報はフレームの総サイズからヘッダサイズを除いたものである(フレームサイズ-10)。

	unsigned char flags[2];	//フレームヘッダフラグ
							/*1バイト目はそのフレームの状態を表すためのフラグであり、2バイト目はエンコードに関するフラグである。
							  1バイト目に認識できないフラグがセットされていた場合で、フレームに変更を加えた場合はそのフラグビットを0にしなくてはならない。
							  もし2バイト目に認識できないフラグがセットされていた場合は、おそらくそのフレームは解析することができないであろう。

								%abc00000 %ijk00000

							a - タグの変更で取り除かれる
								このフラグは、そのフレームをアプリケーションが認識できない場合は、タグに変更が加えられたときに、
								そのフレームを削除しなくてはならないことを示す。
								このことはPadding領域の追加やフレームの順序の変更など、すべての種類の変更の際に適用される。

								0 フレームは保持される 
								1 フレームは除去される 

							b - ファイルの変更で取り除かれる
								このフラグは、そのフレームをアプリケーションが認識できない場合は、ファイル(タグ領域以外)に変更が加えられたときに、
								そのフレームを削除しなくてはならないことを示す。
								このことはオーディオファイルが他のオーディオファイルと完全に置き換えられた場合には適用されない。

								0 フレームは保持される 
								1 フレームは除去される 

							c - 読み込み専用
								このフラグがセットされていた場合は、このフレームが読み込み専用であることを示す。
								このフレームの中身を修正することは、何らかの情報(署名など)を破壊してしまう可能性がある。
								なぜそのフレームが読み込み専用になっているかを考慮せず、適当な代替処理をせずにそのフレームを修正してしまった
								場合(署名を再計算するなど)は、このビットは0にしなくてはならない。


							i - 圧縮
								このフラグはフレームが圧縮されているかを示す。

								0 フレームは圧縮されていない。 
								1 フレームはzlib圧縮されており、フレームヘッダの後に4バイトの「伸張後のサイズ」が格納されている。 

							j - 暗号化
								このフラグはフレームが暗号化されているかどうかを示す。
								もし、暗号化されている場合は、暗号化の手法を示す1バイトのデータが、フレームヘッダの後に格納されている。
								暗号化の手法の登録に関する詳細な説明はセクション4.26を参照せよ。

								0 フレームは暗号化されていない。 
								1 フレームは暗号化されている。 

							k - グループ識別子
								このフラグは、そのフレームが他のフレームとグループを形成しているかどうかを示す。
								もしこのフラグがセットされている場合はグループを識別するための1バイトのデータがフレームヘッダの後に格納されている。
								そこに同じデータが格納されているフレームはすべて同じグループに属するのだ。

								0 フレームにはグループ情報がない。
								1 フレームにはグループ情報が含まれている。


						これらのフラグのうちのいくつかは、セットされることによってフラグが拡張され追加情報が付加される。
						これらの追加情報はフラグの順番と同じ順序でヘッダに追加される。
						たとえば4バイトの伸張後のサイズは暗号化の手法を示す1バイトのデータよりも前に置かれる。
						これらの追加情報のデータ長はフレームヘッダサイズには含められないが、
						フレームサイズ(このフィールドは圧縮や暗号化が行われることはない)には含められる。

							*/
};

と今回は、10バイトのヘッダと、フレームの2つを構造体で定義しました。