PicScrub logoPicScrub
対応形式に戻る

JPEG

いちばん漏れやすい

JPEG ファイルは、ファイルヘッダーと画像データのあいだにある APPn セグメントにメタデータを持っています。どこに何が入っていて、PicScrub がそれぞれをどう扱うのかを見てみましょう。

カラープロファイル、頼めば残す
SOI先頭
APP0JFIF
APP1EXIF
APP1XMP
APP2ICC
APP13IPTC
COMコメント
SOS …ここが本体の写真、無傷
EOI末尾
GPS とカメラ情報はここ、削除
1 バイトも変わらない

削除されるもの

  • EXIF GPS の座標、カメラのメーカーと機種、日時、露出設定
  • XMP 編集履歴、使ったソフト、レーティング
  • IPTC / Photoshop キャプション、クレジット、キーワード
  • コメントと埋め込みサムネイル トリミングや編集をしても残ってしまう、元画像の小さなコピー

残せるもの

  • 画像データ 常に無傷で、再エンコードもしません
  • ICC カラープロファイル 任意。色を正確なまま保てます
  • 向きの情報 任意。縦位置の写真が倒れません
  • 著作権表示 任意。座標は渡さずクレジットだけ残したい人向け

ファイル構造のあらまし

JPEG をバイナリエディタで開いたことがあれば、マーカーで区切られたセグメントの 集まりになっているのが分かるはずです。どのマーカーも 0xFF で始まり、続く 1 バイトがセグメントの種類を表します。 このおかげで JPEG は比較的解析しやすい形式です。FF の バイトを探して、そのあとに何が続くかを見ればいいだけです。

プライバシーの観点で面白いのは、メタデータ(EXIF、GPS、日時)がすべて こうしたセグメントに入っていて、画像データそのものとは完全に分かれている ことです。だからこそ、ピクセルに触れず、再圧縮もせずにメタデータだけを 取り除けます。

JPEG のファイル構造

SOI
APP0-15
DQT
SOF
DHT
SOS + Data
EOI
SOI
2 バイト
画像の開始 (FF D8)
APP0-15
100 バイト
アプリケーションマーカー(メタデータ)
DQT
130 バイト
量子化テーブル
SOF
20 バイト
フレームの開始
DHT
420 バイト
ハフマンテーブル
SOS + Data
可変長
スキャンデータ(画像そのもの)
EOI
2 バイト
画像の終了 (FF D9)

JPEG ヘッダーの例

SOI(画像の開始)
APP0 マーカー
APP0 の長さ
JFIF 識別子
JFIF データ
APP1 マーカー
APP1 の長さ
Exif 識別子
OffsetHexASCII
0000
FFD8FFE000104A464946000101000048
......JFIF.....H
0010
00480000FFE112344578696600000000
.H.....4Exif..

マーカーの構造

  • FF xx:マーカー(xx が種類を表します)
  • LL LL:長さ(2 バイト、ビッグエンディアン、 この 2 バイト自身を含みます)
  • Data...:セグメントのデータ(長さ - 2 バイト)

JPEG マーカー一覧

マーカー名前説明
FF D8SOI画像の開始
FF D9EOI画像の終了
FF C0SOF0フレームの開始(ベースライン DCT)
FF C2SOF2フレームの開始(プログレッシブ DCT)
FF C4DHTハフマンテーブルの定義
FF DBDQT量子化テーブルの定義
FF DDDRIリスタート間隔の定義
FF DASOSスキャンの開始(この後ろに画像データが続きます)
FF FECOMコメント(メタデータ)
FF E0APP0JFIF マーカー
FF E1APP1EXIF / XMP マーカー
FF E2APP2ICC プロファイル / MPF
FF EDAPP13IPTC / Photoshop
FF EEAPP14Adobe の色変換

金色 = メタデータ(削除)、無地 = 残る構造

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 バイト)

バイトオーダー(II = リトルエンディアン)
マジックナンバー(42)
IFD0 のオフセット
OffsetHexASCII
0000
49492A0008000000
II*.....

II = Intel(リトルエンディアン)、MM = Motorola(ビッグエンディアン)

IFD エントリの構造(12 バイト)

Tag IDTypeCountValue/Offset
2 バイト2 バイト4 バイト4 バイト

主な IFD エントリ

0x010F:Make
0x0110:Model
0x0132:DateTime
0x8769:ExifIFDPointer
0x8825:GPSInfoIFDPointer
0x927C:MakerNote

PicScrub が JPEG を処理する流れ

やり方はとても素直です。ファイルをマーカー単位で読み進め、画像を表示する のに必要なものは残し、メタデータが入っているものは読み飛ばします。 圧縮された画像データには一切触れないので、画質の劣化はゼロです。

ポイントは、JPEG のマーカーベースの構造がこれを簡単にしてくれることです。 DCT の係数やハフマンテーブルを理解する必要はありません。どのセグメントが メタデータで、どれがそうでないかを見分けられれば十分です。

1

ヘッダーの検証

ファイル先頭の SOI マーカー(FF D8)を確認します

2

マーカーの解析

マーカーを順に読み、種類と長さを取り出します

3

メタデータの判別

APP セグメント内の識別子を調べます(EXIF、XMP、IPTC など)

4

選んでコピー

メタデータ以外のセグメントを出力にコピーし、メタデータは飛ばします

残るもの

  • • SOI/EOI マーカー(必須)
  • • DQT(量子化テーブル)
  • • SOF(フレームヘッダー)
  • • DHT(ハフマンテーブル)
  • • SOS とスキャンデータ(画像そのもの)
  • • 任意: ICC カラープロファイル(設定で切り替え)

削除されるもの

  • • APP1 の EXIF(カメラ、GPS、日時)
  • • APP1 の XMP(編集のメタデータ)
  • • APP13 の IPTC(キャプション、作成者)
  • • COM マーカー(コメント)
  • • EXIF のサムネイル画像

EXIF タグ一覧

プライバシーという点では、EXIF タグの危険度は一様ではありません。 露出設定のようにほぼ無害なものもあれば、シリアル番号や所有者名のように あなたや機材を特定できてしまうものもあります。リスクが高いと考えている のは次のタグです。

タグ ID名前プライバシーリスク
0x9003DateTimeOriginal高
0x9004DateTimeDigitized高
0x9010OffsetTime中
0x9286UserComment高
0x927CMakerNote高
0xA420ImageUniqueID高
0xA430CameraOwnerName高
0xA431BodySerialNumber高
0xA434LensModel中
0xA435LensSerialNumber高
0xFDE8OwnerName高
0xFDE9SerialNumber高
カメラの設定に関するタグをすべて見る(個人特定にはつながりません)
0x829A ExposureTime
0x829D FNumber
0x8822 ExposureProgram
0x8827 ISOSpeedRatings
0x9201 ShutterSpeedValue
0x9202 ApertureValue
0x9203 BrightnessValue
0x9204 ExposureBiasValue
0x9207 MeteringMode
0x9208 LightSource
0x9209 Flash
0x920A FocalLength
0xA001 ColorSpace
0xA002 PixelXDimension
0xA003 PixelYDimension
0xA402 ExposureMode
0xA403 WhiteBalance
0xA405 FocalLengthIn35mmFilm
0xA406 SceneCaptureType

GPS タグ一覧

GPS のデータは専用のサブ IFD に入っていて、メイン IFD の 0x8825 タグがそこを指しています。このポインタがあれば、 画像に位置情報が入っているということです。最近のスマートフォンは とくに積極的にこれを埋め込みます。しかも、どこに立っていたかまで 分かるほどの精度であることも珍しくありません。

タグ ID名前説明
0x0000GPSVersionIDGPS タグのバージョン
0x0001GPSLatitudeRefN か S
0x0002GPSLatitude度、分、秒
0x0003GPSLongitudeRefE か W
0x0004GPSLongitude度、分、秒
0x0005GPSAltitudeRef海抜の上か下か
0x0006GPSAltitudeメートル
0x0007GPSTimeStampUTC の時刻
0x001DGPSDateStampUTC の日付
0x0012GPSMapDatum測地系のデータ
0x001BGPSProcessingMethodGPS/CELLID/WLAN/MANUAL
0x001CGPSAreaInformation場所の名前

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(キーワード)