JPEG
いちばん漏れやすいJPEG ファイルは、ファイルヘッダーと画像データのあいだにある APPn セグメントにメタデータを持っています。どこに何が入っていて、PicScrub がそれぞれをどう扱うのかを見てみましょう。
削除されるもの
- EXIF GPS の座標、カメラのメーカーと機種、日時、露出設定
- XMP 編集履歴、使ったソフト、レーティング
- IPTC / Photoshop キャプション、クレジット、キーワード
- コメントと埋め込みサムネイル トリミングや編集をしても残ってしまう、元画像の小さなコピー
残せるもの
- 画像データ 常に無傷で、再エンコードもしません
- ICC カラープロファイル 任意。色を正確なまま保てます
- 向きの情報 任意。縦位置の写真が倒れません
- 著作権表示 任意。座標は渡さずクレジットだけ残したい人向け
ファイル構造のあらまし
JPEG をバイナリエディタで開いたことがあれば、マーカーで区切られたセグメントの 集まりになっているのが分かるはずです。どのマーカーも 0xFF で始まり、続く 1 バイトがセグメントの種類を表します。 このおかげで JPEG は比較的解析しやすい形式です。FF の バイトを探して、そのあとに何が続くかを見ればいいだけです。
プライバシーの観点で面白いのは、メタデータ(EXIF、GPS、日時)がすべて こうしたセグメントに入っていて、画像データそのものとは完全に分かれている ことです。だからこそ、ピクセルに触れず、再圧縮もせずにメタデータだけを 取り除けます。
JPEG のファイル構造
JPEG ヘッダーの例
| Offset | Hex | ASCII | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0000 | FFD8FFE000104A464946000101000048 | ......JFIF.....H | |||||||||||||||
| 0010 | 00480000FFE112344578696600000000 | .H.....4Exif.. | |||||||||||||||
マーカーの構造
FF xx:マーカー(xx が種類を表します)LL LL:長さ(2 バイト、ビッグエンディアン、 この 2 バイト自身を含みます)Data...:セグメントのデータ(長さ - 2 バイト)
JPEG マーカー一覧
| マーカー | 名前 | 説明 |
|---|---|---|
| FF D8 | SOI | 画像の開始 |
| FF D9 | EOI | 画像の終了 |
| FF C0 | SOF0 | フレームの開始(ベースライン DCT) |
| FF C2 | SOF2 | フレームの開始(プログレッシブ DCT) |
| FF C4 | DHT | ハフマンテーブルの定義 |
| FF DB | DQT | 量子化テーブルの定義 |
| FF DD | DRI | リスタート間隔の定義 |
| FF DA | SOS | スキャンの開始(この後ろに画像データが続きます) |
| FF FE | COM | コメント(メタデータ) |
| FF E0 | APP0 | JFIF マーカー |
| FF E1 | APP1 | EXIF / XMP マーカー |
| FF E2 | APP2 | ICC プロファイル / MPF |
| FF ED | APP13 | IPTC / Photoshop |
| FF EE | APP14 | Adobe の色変換 |
金色 = メタデータ(削除)、無地 = 残る構造
JFIF と EXIF の違い
ここは多くの人が混乱するところです。JPEG ファイルには、2 つの 異なるメタデータ規格が同時に入っていることがよくあります。先に登場したのが JFIF で、解像度などの基本的な情報を扱います。その後、カメラが撮影時の 詳しい情報を EXIF として書き込むようになりました。最近の JPEG はたいてい 両方持っているので、ファイルの先頭付近に APP0 と APP1 の両方のマーカーが 並んでいるわけです。
APP0:JFIF
JPEG File Interchange Format。画像の基本情報です。
- • バージョン番号
- • 画素密度(DPI)
- • アスペクト比
- • サムネイル(任意)
APP1:EXIF
Exchangeable Image File Format。カメラのメタデータです。
- • カメラのメーカーと機種
- • GPS の座標
- • 日時
- • 露出設定
APP マーカーを掘り下げる
JPEG の仕様では、ベンダーが自由に使える「アプリケーション」マーカーが 16 個(APP0 から APP15)予約されています。長年のあいだに、いろいろな団体が 自分たちのメタデータ形式のためにそれぞれのマーカーを使い始めました。 結果として少々ごちゃごちゃしていますが、少なくともきちんと文書化された ごちゃごちゃです。
やっかいなのは、同じマーカーでも中身によって意味が変わることです。 たとえば APP1 は EXIF のことも XMP のこともあるので、中の識別子文字列を 見ないとどちらなのか分かりません。
APP0 (0xFFE0):JFIF
識別子: JFIF\0。バージョン、密度の単位、X/Y の密度、 そして任意で埋め込みサムネイルが入ります。基本的には残しても 問題ありません。
APP1 (0xFFE1):EXIF
識別子: Exif\0\0。カメラ情報、GPS データ、日時、 サムネイル、メーカーノートなどの IFD エントリを持つ、 完全な TIFF 構造が入っています。 プライバシー上いちばん注意すべき部分です。
APP1 (0xFFE1):XMP
識別子: http://ns.adobe.com/xap/1.0/\0。Adobe による XML ベースのメタデータ規格です。編集履歴、ソフトの情報、 拡張された EXIF データが入ることがあります。
XMP の名前空間
xmp: http://ns.adobe.com/xap/1.0/xmpMM: http://ns.adobe.com/xap/1.0/mm/dc: http://purl.org/dc/elements/1.1/photoshop: http://ns.adobe.com/photoshop/1.0/tiff: http://ns.adobe.com/tiff/1.0/exif: http://ns.adobe.com/exif/1.0/APP1 (0xFFE1):拡張 XMP
識別子: http://ns.adobe.com/xmp/extension/\0。65KB を超える XMP データを、複数の APP1 セグメントに分割して格納します。
APP2 (0xFFE2):MPF
識別子: MPF\0。ステレオ画像やパノラマのための Multi-Picture Format です。
APP2 (0xFFE2):ICC プロファイル
識別子: ICC_PROFILE\0。カラーマネジメントのデータです。 複数の APP2 マーカーに分割されることもあります。 たいていは残しても問題ありません。
APP13 (0xFFED):IPTC/Photoshop
識別子: Photoshop 3.0\0。キャプション、キーワード、 著作権、作成者情報などの IPTC-IIM データが入ります。 作成者の情報が含まれることがあります。
APP14 (0xFFEE):Adobe
識別子: Adobe\0。色変換のフラグ(RGB/CMYK)が 入っています。色を正しく表示するために重要です。
EXIF の構造
ここからが面白い(そして少し変わった)ところです。EXIF データの正体は、 JPEG の中に埋め込まれた小さな TIFF ファイルです。本当です。独自の ヘッダーを持ち、独自のバイトオーダーを持ち、タグの格納には TIFF の IFD(Image File Directory)構造を使います。
「Exif」の識別子のすぐあとに現れるのが TIFF ヘッダーで、データが リトルエンディアン(Intel、「II」)かビッグエンディアン(Motorola、「MM」) かを示します。ここを取り違えると数値がすべてでたらめになるので、 どのパーサーも真っ先に確認します。
TIFF ヘッダー(8 バイト)
| Offset | Hex | ASCII | |||||||
|---|---|---|---|---|---|---|---|---|---|
| 0000 | 49492A0008000000 | II*..... | |||||||
II = Intel(リトルエンディアン)、MM = Motorola(ビッグエンディアン)
IFD エントリの構造(12 バイト)
主な IFD エントリ
0x010F:Make0x0110:Model0x0132:DateTime0x8769:ExifIFDPointer0x8825:GPSInfoIFDPointer0x927C:MakerNotePicScrub が JPEG を処理する流れ
やり方はとても素直です。ファイルをマーカー単位で読み進め、画像を表示する のに必要なものは残し、メタデータが入っているものは読み飛ばします。 圧縮された画像データには一切触れないので、画質の劣化はゼロです。
ポイントは、JPEG のマーカーベースの構造がこれを簡単にしてくれることです。 DCT の係数やハフマンテーブルを理解する必要はありません。どのセグメントが メタデータで、どれがそうでないかを見分けられれば十分です。
ヘッダーの検証
ファイル先頭の SOI マーカー(FF D8)を確認します
マーカーの解析
マーカーを順に読み、種類と長さを取り出します
メタデータの判別
APP セグメント内の識別子を調べます(EXIF、XMP、IPTC など)
選んでコピー
メタデータ以外のセグメントを出力にコピーし、メタデータは飛ばします
残るもの
- • SOI/EOI マーカー(必須)
- • DQT(量子化テーブル)
- • SOF(フレームヘッダー)
- • DHT(ハフマンテーブル)
- • SOS とスキャンデータ(画像そのもの)
- • 任意: ICC カラープロファイル(設定で切り替え)
削除されるもの
- • APP1 の EXIF(カメラ、GPS、日時)
- • APP1 の XMP(編集のメタデータ)
- • APP13 の IPTC(キャプション、作成者)
- • COM マーカー(コメント)
- • EXIF のサムネイル画像
EXIF タグ一覧
プライバシーという点では、EXIF タグの危険度は一様ではありません。 露出設定のようにほぼ無害なものもあれば、シリアル番号や所有者名のように あなたや機材を特定できてしまうものもあります。リスクが高いと考えている のは次のタグです。
| タグ ID | 名前 | プライバシーリスク |
|---|---|---|
| 0x9003 | DateTimeOriginal | 高 |
| 0x9004 | DateTimeDigitized | 高 |
| 0x9010 | OffsetTime | 中 |
| 0x9286 | UserComment | 高 |
| 0x927C | MakerNote | 高 |
| 0xA420 | ImageUniqueID | 高 |
| 0xA430 | CameraOwnerName | 高 |
| 0xA431 | BodySerialNumber | 高 |
| 0xA434 | LensModel | 中 |
| 0xA435 | LensSerialNumber | 高 |
| 0xFDE8 | OwnerName | 高 |
| 0xFDE9 | SerialNumber | 高 |
カメラの設定に関するタグをすべて見る(個人特定にはつながりません)
0x829A ExposureTime0x829D FNumber0x8822 ExposureProgram0x8827 ISOSpeedRatings0x9201 ShutterSpeedValue0x9202 ApertureValue0x9203 BrightnessValue0x9204 ExposureBiasValue0x9207 MeteringMode0x9208 LightSource0x9209 Flash0x920A FocalLength0xA001 ColorSpace0xA002 PixelXDimension0xA003 PixelYDimension0xA402 ExposureMode0xA403 WhiteBalance0xA405 FocalLengthIn35mmFilm0xA406 SceneCaptureTypeGPS タグ一覧
GPS のデータは専用のサブ IFD に入っていて、メイン IFD の 0x8825 タグがそこを指しています。このポインタがあれば、 画像に位置情報が入っているということです。最近のスマートフォンは とくに積極的にこれを埋め込みます。しかも、どこに立っていたかまで 分かるほどの精度であることも珍しくありません。
| タグ ID | 名前 | 説明 |
|---|---|---|
| 0x0000 | GPSVersionID | GPS タグのバージョン |
| 0x0001 | GPSLatitudeRef | N か S |
| 0x0002 | GPSLatitude | 度、分、秒 |
| 0x0003 | GPSLongitudeRef | E か W |
| 0x0004 | GPSLongitude | 度、分、秒 |
| 0x0005 | GPSAltitudeRef | 海抜の上か下か |
| 0x0006 | GPSAltitude | メートル |
| 0x0007 | GPSTimeStamp | UTC の時刻 |
| 0x001D | GPSDateStamp | UTC の日付 |
| 0x0012 | GPSMapDatum | 測地系のデータ |
| 0x001B | GPSProcessingMethod | GPS/CELLID/WLAN/MANUAL |
| 0x001C | GPSAreaInformation | 場所の名前 |
IPTC タグ一覧
IPTC は、通信社がキャプションやクレジット、著作権情報を埋め込むために 作られた規格です。「Photoshop 3.0」という識別子とともに APP13 に格納 されます(そう、Adobe が採用したのです)。Lightroom や Photoshop で 著作権情報やキーワードを入力したことがあるなら、それはここに入っています。
0x0250 By-line(作成者)0x0255 By-line Title(肩書き)0x025A City(市区町村)0x025C Sub-location(詳細な場所)0x025F Province/State(都道府県・州)0x0265 Country Name(国名)0x0274 Copyright Notice(著作権表示)0x0276 Contact(連絡先)0x0237 Date Created(作成日)0x023C Time Created(作成時刻)0x0278 Caption/Abstract(キャプション)0x0219 Keywords(キーワード)