Exifファイルから生データを取り出す方法。
そのデータが何を示すものなのかについては考えずとりあえず取り出す。
以下はExifファイルをその先頭から16進ダンプしたもの。
そのデータが何を示すものなのかについては考えずとりあえず取り出す。
以下はExifファイルをその先頭から16進ダンプしたもの。
0000: FF D8 FF E1 3D 6A 45 78 69 66 00 00 4D 4D 00 2A ① ② ③ ④ ⑤ ⑥ ① SOI マーカー ② APP1 マーカー ③ APP1 サイズ ④ Exifマーカー ('Exif\0\0') ⑤ 数値格納形式 49 49('II') : インテル形式 4D 4D('MM') : モトローラ形式 ⑥ TAGマーカー 【 ステップ1 】 Exifファイルを開き先頭から12バイトを読みこむ。 【 ステップ2 】 ここで①、②、④は1部*1のExifファイルを除き同じ値を取る。つまり、0000~ 000Bまでの③に対応する2バイト以外をファイルに入っている値と比較し同じであ ればExifファイルとして処理を続行、異なればExifファイルではないと判断し、 処理を終了する。 ※ CASIOなどの1部の古いデジカメではこの形の格納形式のExif ファイルではないためこの判断方法ではExifファイルとして 認識されない。 【 ステップ3 】 ③に対応するAPP1サイズの2バイト値をSHORTとして取得する。 その際「3D 6A」という値はそのまま「0x3D6A」とする点に注意。 ここで「取得したバイト数-6byte*」をExifファイルから読みこむ。 ※ 6バイトというのは④に相当するサイズ 【 ステップ4 】 ⑤に対応する数値格納形式を取得し 49 49('II') : インテル形式 4D 4D('MM') : モトローラ形式 のどちらかを判定する。このExifファイルでは4D 4Dなのでモトローラ形式。 インテル形式 : 「0x12345678」は「78 56 34 12」という形で格納 モトローラ形式 : 「0x12345678」は「12 34 56 78」という形で格納 【 ステップ5 】 ⑥を確認する。ここではモトローラ形式なので「00 2A」と格納されている。 インテル形式であれば「2A 00」となる。どちらの場合も示す値は0x002A。これ はどのExifファイルでもこの値を取る。 0010: 00 00 00 08 00 0B 01 0F 00 02 00 00 00 09 00 00 ① ② ③ ④ ⑤ ⑥ 0020: 00 92 01 10 00 02 00 00 00 0D 00 00 00 9C 01 12 2番目 3番目 ① 1番目のディレクトリへのオフセット ② ディレクトリ・エントリ数 【 1番目のディレクトリの開始 】 ③ ディレクトリ・タグ ④ 格納値タイプ 1 : BYTE (8bit unsigned integer) 2 : ASCII (NULLで終わる文字列) 3 : SHORT (16bit unsigned integer) 4 : LONG (32bit unsigned integer) 5 : RATIONAL (2つのLONGの比; unsigned double) 6 : 未定義 7 : Undefined (8bit値) 8 : 未定義 9 : SLONG (32bit signed integer) 10 : SRATIONAL (2つのSLONGの比; signed double) ⑤ 格納値数 ⑥ オフセットもしくは格納値 【 1番目のディレクトリの終了 】 【 ステップ6 】 ①のオフセットを取得する。ここで示される値「0x00000008」はファイルの先頭 12バイト目から始まる「TAGマーカー」欄からのバイト数を示す。つまり、アドレス 0016から1つ目のディレクトリ・エントリが始まる。 【 ステップ7 】 ②のディレクトリ・エントリ数を取得する。ここで示される値「0x000B」は11コ のディレクトリ・エントリが存在することを示す。 【 ステップ8 】 ステップ6で取得したオフセットからステップ7で取得した数だけディレクトリ・ エントリを取得する。 1つのディレクトリ・エントリは12バイト+αから構成される。そのため、まず は1つ分の12バイトを読みこむ。 【 ステップ9 】 以下の値をそれぞれ取得し保存する。 ③のディレクトリ・タグ ④の格納値タイプ ⑤の格納値数 ⑥のオフセットもしくは格納値 ここで⑥がオフセットを示す場合には示されるオフセット位置にデータが格納さ れている。格納値を示す場合には⑥に相当する4バイトのすべてもしくは1部がその ディレクトリ・エントリの値となる。 ⑥がオフセットを示すのかそれともそのまま格納値なのかは④と⑤の2つを見て 判断する必要がある。④と⑤によって示されるデータのバイト数が4バイトを超え ない場合には⑥の値がそのままデータに、4バイトを超える場合にはオフセット値 となる。 例えば④の格納値タイプが0x0004=LONGであり、⑤の格納値数が0x0001=1つで あればLONGが1つ分の計4バイトの情報があることがわかる。⑥の領域も4バイトあ るのでこの場合は⑥がそのまま格納値となる。 例えば④の格納値タイプが0x0003=SHORTであり、⑤の格納値数が0x0001=1つで あればSHORTが1つ分の計2バイトの情報があることがわかる。⑥の領域は4バイトあ るので、この場合は⑥がそのまま格納値となる。ただしデータとなる2バイトは⑥の 領域の左側から格納される。 例えば④の格納値タイプが0x0005=RATIONALであり、⑤の格納値数が0x0001=1 つであればRATIONALはLONGが2つなので計8バイトの情報があることがわかる。⑥ の領域も4バイトあるのでこの場合は⑥に格納できないのでオフセット値となる。 実際の値はファイルの先頭から「オフセット値+12バイト*」にある8バイトの前半 4バイトをA、後ろ4バイトをBとすると「示す値=A÷B」となる。 例えば④の格納値タイプが0x0002=ASCIIであり、⑤の格納値数が0x0009=9つで あればASCII文字が9つ分の計9バイトの情報があることがわかる。この場合も⑥は オフセットを示し、ファイルの先頭から「オフセット値+12バイト*」の位置にある 9バイトの文字列がデータとなる。このとき9バイト目はNULLとなる。 ※ 12バイトというのは0000~000C、つまりSOIからExifマーカーの終わ りまでのバイト数による 【 ステップ10 】 ステップ7で取得したディレクトリ・エントリ数分だけ同様に処理する。 0030: 00 03 00 00 00 01 00 01 00 00 01 1A 00 05 00 00 4番目 0040: 00 01 00 00 00 AA 01 1B 00 05 00 00 00 01 00 00 5番目のIFD 0050: 00 B2 01 28 00 03 00 00 00 01 00 02 00 00 01 31 6番目 7番目 0060: 00 02 00 00 00 24 00 00 00 BA 01 32 00 02 00 00 8番目 0070: 00 14 00 00 00 DE 02 13 00 03 00 00 00 01 00 02 9番目のIFD 0080: 00 00 82 98 00 02 00 00 00 0B 00 00 00 F2 87 69 10番目 11番目 0090: 00 04 00 00 00 01 00 00 00 FE 00 00 03 8C 46 55 ① ② 00A0: 4A 49 46 49 4C 4D 00 00 46 69 6E 65 50 69 78 53 ① 次のIFDへのオフセット??????????? ② 1番目のディレクトリが示すデータ 00B0: 31 50 72 6F 00 00 00 00 00 48 00 00 00 01 00 00 00C0: ..............
