TIFF 形式
Tagged Image File Format
ヘッダーの構造
TIFF は画像メタデータの祖先のような存在です。JPEG の中に見える EXIF データも、その正体はファイルに埋め込まれた TIFF 構造です。TIFF を 理解することは、ほとんどの画像メタデータの仕組みを理解することでもあります。
ファイルは 8 バイトのヘッダーで始まり、そこで 2 つの大事なことが決まります。 バイトオーダー(Intel か Motorola か)と、最初の IFD がどこにあるかです。 そこから先はひたすらポインタをたどる旅になります。
TIFF のファイル構造
TIFF のヘッダー
| Offset | Hex | ASCII | |||||||
|---|---|---|---|---|---|---|---|---|---|
| 0000 | 49492A0008000000 | II*..... | |||||||
バイトオーダー
49 49 (II)Intel:リトルエンディアン(下位バイトが先)
4D 4D (MM)Motorola:ビッグエンディアン(上位バイトが先)
IFD の構造
IFD は Image File Directory の略ですが、目次だと思うと分かりやすい でしょう。タグが平坦に並んだリストで、それぞれが何かのデータを 指しています。うまくできているのは、IFD が別の IFD を指せることです。 これでツリー構造が作れます。
IFD のレイアウト
タグエントリの構造(12 バイト)
データが 4 バイトに収まるなら、値フィールドに直接入ります。 収まらない場合は、値フィールドにデータへのオフセットが入ります。
タグの型
TIFF は型に厳格です。各タグは何が入っているかだけでなく、バイトを どう解釈すべきかも指定します。TIFF を正しく解析するには、この型の 仕組みを理解しておく必要があります。
| ID | 名前 | サイズ | 説明 |
|---|---|---|---|
| 1 | BYTE | 1 | 符号なし 8 ビット整数 |
| 2 | ASCII | 1 | ヌル終端の文字列(8 ビット) |
| 3 | SHORT | 2 | 符号なし 16 ビット整数 |
| 4 | LONG | 4 | 符号なし 32 ビット整数 |
| 5 | RATIONAL | 8 | LONG が 2 つ(分子と分母) |
| 6 | SBYTE | 1 | 符号付き 8 ビット整数 |
| 7 | UNDEFINED | 1 | 生のバイト列(バイナリデータ) |
| 8 | SSHORT | 2 | 符号付き 16 ビット整数 |
| 9 | SLONG | 4 | 符号付き 32 ビット整数 |
| 10 | SRATIONAL | 8 | SLONG が 2 つ(符号付きの分子と分母) |
| 11 | FLOAT | 4 | IEEE 32 ビット浮動小数点数 |
| 12 | DOUBLE | 8 | IEEE 64 ビット倍精度 |
| 13 | IFD | 4 | 入れ子の IFD へのポインタ |
値の格納ルール
size × count ≤ 4 バイトなら、値は 4 バイトの値フィールドに 直接入ります。そうでなければ、そのフィールドにはファイル内のデータ位置を 指すオフセットが入ります。
IFD オフセットの計算
TIFF の解析でいちばん難しいのは、オフセットの連鎖をたどることです。 すべてがファイル先頭からの相対位置なので、あちこち飛び回ることに なります。計算はこんなふうになります。
IFD0_offset = bytes[4:8] // TIFF ヘッダーから
next_IFD = IFD0_offset + 2 + (entry_count × 12) + 4
subIFD_offset = tag_value // ポインタタグ(0x8769、0x8825)から
主なタグ
画像データのタグ(残します)
0x0100:ImageWidth0x0101:ImageLength0x0102:BitsPerSample0x0103:Compression0x0111:StripOffsets0x0117:StripByteCountsメタデータのタグ(削除します)
0x010F:Make(カメラのメーカー)0x0110:Model(カメラの機種)0x0132:DateTime0x013B:Artist0x8298:Copyright0x9003:DateTimeOriginalポインタのタグ(サブ IFD)
0x8769:ExifIFDPointer0x8825:GPSInfoIFDPointer0xA005:InteroperabilityIFDPointerサブ IFD
メインの IFD(IFD0)には、サブディレクトリを指す「ポインタタグ」が 入っていることがよくあります。こうして EXIF や GPS などのメタデータを 意味のあるグループにまとめつつ、メインの IFD をすっきり保っています。
EXIF のサブ IFD
カメラ固有のメタデータが入ります。露出、絞り、ISO、焦点距離、 フラッシュ、ホワイトバランスなどです。
GPS のサブ IFD
位置情報が入ります。緯度、経度、高度、時刻、衛星、速度、方位。 プライバシー上とくに注意すべき部分です。
メーカーノート
カメラメーカー独自のデータ。形式はメーカーごとに違います。 シリアル番号、ファームウェアのバージョン、独自の設定が 入っていることがあります。
PicScrub が TIFF を処理する流れ
ヘッダーの解析
バイトオーダー(II/MM)を判定し、最初の IFD の位置を突き止めます
残すタグの選定
画像の表示に欠かせないタグを洗い出します
IFD エントリの選別
メタデータのタグを削除し、サブ IFD へのポインタをゼロにします
ファイルの書き直し
きれいになった IFD と、そのままコピーした画像データで TIFF を組み直します
オフセットの再計算
TIFF はファイル内のオフセットを大量に使います。メタデータを削除したら、 PicScrub はファイルの整合性を保つためにすべてのオフセットを 計算し直さなければなりません。