THETA Sのサンプルの静止画像(.jpg)のメタデータをパースしてみた


来月下旬(Amazonでは10/30販売となっている)、THETAの新機種であるTHETA Sが販売されます。
そこで、サンプルの動画は公開されていませんが、サンプルの静止画像はアプリで取得することができますのでサンプルの静止画像のメタデータをパースしてみました。

記録されているセグメント構成

使用されているマーカセグメント

JPEGファイルは、マーカセグメントと呼ばれる単位で構成されています。
マーカセグメントは単にセグメントと呼ばれるほうが多いようです。
文中もまた、以降、マーカセグメントを単にセグメントと呼ぶことにします。
サンプル画像で使用されているセグメントを表にまとめてみます。

マーカ名
(*は必須のマーカセグメント)
マーカ値 説明
*SOI
(Start of Image)
FFD8 JPEGファイルの先頭に必ず配置されるマーカ。
このSOIと最後のEOIはマーカのみの構成となっている。(2バイト)
*APP1
(Application Segment 1)
FFE1 このセグメントは2つ記録される。
一つのAPP1セグメントにはExifが、もう一つのAPP1セグメントにはXMPが記録される。
APP13
(Application Segment 13)
FFED Adobe PhotoShopの情報が記録されるセグメント。
*SOF0
(Start of Frame)
FFC0 フレームセグメントの始まりに位置し、そのフレームの各種パラメータが
このセグメントに記録される。
SOFには、0~3,5~7,9~11,13~15(4,8,12はない)があり、
SOF0はハフマン式ベースラインDCTのフレームパラメータが記録される。
*DHT
(Define Huffman Table)
FFC4 ハフマンテーブル
*DQT
(Define Quantization Table)
FFDB 量子化テーブル
DRI
(Define Restart Interval)
FFDD リスタートインターバル
*SOS(RSTn)
(Start of Scan)
FFDA このセグメントの直後にスキャンデータ(画像データ)が記録される。また、DRIが記録されているため、スキャンデータ中にはRSTn(nは0~7)のセグメントも記録される。
*EOI
(End of Image)
FFD9 JPEGファイルの最後に必ず配置されるマーカ。

THETA Sのセグメント構成(記録順)

ここで、サンプル画像に記録されているセグメントを記録順に並べてみます。

セグメント(記録順)
SOI
APP1(Exif)
APP1(XMP)
APP13
APP13
SOF
DHT
DHT
DHT
DHT
DQT
DQT
DRI
SOS
EOI

すると、APP1やAPP13、またDHTやDQTが複数記録されていることがわかります。
ただ、ここで問題があります。
JEITAのExif 2.3 規格書において、
APP1やAPP13などのAPPnのセグメントについては、

(APPn) このマーカの記載は任意であり、必要に応じて複数個記録することが可能である。(APP1, APP2を含む)
http://www.jeita.or.jp/japanese/standard/book/CP-3451C_J/#page=25

となっており、APPnに関しては複数記録してもよいとされていますが、

DQTやDHTのセグメントについては、

・量子化テーブルは、すべてを一つのDQTマーカセグメント内に記録しなければならない(DQTマーカを複数記録してはならない)。
http://www.jeita.or.jp/japanese/standard/book/CP-3451C_J/#page=89

・ハフマンテーブルは、すべてを一つのDHTマーカセグメント内に記録しなければならない(DHTマーカを複数記録してはならない)。
http://www.jeita.or.jp/japanese/standard/book/CP-3451C_J/#page=90

と書かれておりますので、Exif 2.3の規格には沿っていないと思われます。
よって、JPEGのメタデータを取得するアプリなどで画像を読み込むとすべてのDQTやDHTのセグメントを読み込まないなどの問題が起きるかもしれません。

メタデータ

続いて、サンプル画像に記録されているメタデータ(Exif, XMP, APP13)を見てみます。

EXif

ExifはIFD(Image File Directory)という単位で構成されており、IFDには0th IFD, Exif IFD, InterOperability IFD, GPS IFD, 1st IFDの5つのIFDがあります。
Exifの仕様においては0th IFDは必須で、それ以外のIFDは任意となっています。

0th IFD

タグ名 データ型 データの個数(サイズ)
ImageDescription
(タイトルまたは名前)
ASCII 64 " " (スペース63個)
Make
(カメラ本体のメーカー名)
ASCII 22 "RICHO                 "
Model
(カメラ本体のモデル名)
ASCII 64 "RICOH THETA S                                                  "
Orientation
(イメージの向き)
SHORT 1 1 (向き補正なし)
XResolution
(画像の幅の解像度)
RATIONAL 1 72/1 (72dpi)
YResolution
(画像の高さの解像度)
RATIONAL 1 72/1 (72dpi)
ResolutionUnit
(画像の幅と高さの解像度の単位)
SHORT 1 2 (インチ)
Software
(ファームウェアのソフトウェア名称)
ASCII 32 "RICOH THETA S Ver 0.71         "
DateTime
(作成時刻または更新時刻)
ASCII 20 "2015:05:19 20:48:00"
YCbCrPositioning
(YCCの画素構成[YとCの位置])
SHORT 1 1 (中心)
Copyright
(コピーライト)
ASCII 46 " "(スペース45個)

Exif IFD

データ名 データ型 データの個数(サイズ)
ExposureTime
(露光時間)
RATIONAL 1 1/30秒
FNumber
(F値)
RATIONAL 1 2/1 (2.0)
ExposureProgram
(露光プログラム)
SHORT 1 2 (ノーマルプログラム)
ISOSpeedRatings
(ISO感度)
SHORT 1 400
SensitivityType
(感度種別)
SHORT 1 1 (標準出力感度[SOS])
ExifVersion
(EXIFサポートバージョン)
UNDEFINED 4 "0230" (ver2.30)
DateTimeOriginal
(現画像データの生成日時)
ASCII 20 "2015:05:19 20:48:00"
CreateDate
(デジタルデータの作成日時)
ASCII 20 "2015:05:19 20:48:00"
ComponentsConfiguration
(各コンポーネントの意味)
UNDEFINED 4 1, 2, 3, 0 (Y, Cb, Cr, _)
CompressedBitsPerPixel
(画像圧縮モード)
RATIONAL 1 16/5
ApertureValue
(絞り値)
RATIONAL 1 2/1 (2)
BrightnessValue
(輝度値)
SRATIONAL 1 -1/10 (-0.1)
ExposureBiasValue
(露出補正値)
SRATIONAL 1 0/1 (0)
MaxApertureValue
(レンズ最小F値)
RATIONAL 1 2/1 (2.0)
MeteringMode
(測光方式)
SHORT 1 5 (分割測光)
LightSource
(光源)
SHORT 1 0 (不明)
Flash
(フラッシュ露光)
SHORT 1 0 (ストロボ発行なし/ストロボのリターン検出機能なし/カメラのストロボモード不明/ストロボ機能あり/赤目軽減機能なしまたは不明)
FocalLength
(焦点距離)
RATIONAL 1 131/100 (1.31mm?)
UserCOmment
(コメント)
UNDEFINED 264 "r=11585[2015.5.15]@ZRFG030058 "
FlashpixVersion
(対応 Fraspix バージョン)
UNDEFINED 4 "0100" (ver 1.0)
ColorSpace
(色空間)
SHORT 1 1 (sRGB)
PixelXDimension
(実効画像幅)
LONG 1 5376
PixelYDimension
(実効画像高さ)
LONG 1 2688
ExposureMode
(露出モード)
SHORT 1 0 (露出自動)
WhiteBalance
(ホワイトバランス)
SHORT 1 0 (ホワイトバランス自動)
SceneCaptureType
(撮影シーンタイプ)
SHORT 1 0 (標準)
Sharpness
(シャープネス)
SHORT 1 0 (標準)

GPS IFD

データ名 データ型 データの個数(サイズ)
GPSVersionID
(GPS タグのバージョン)
BYTE 4 2, 3, 0, 0 (ver2.3)
GPSImgDirectionRef
(撮影した画像の方向の単位)
ASCII 2 "T" (真方位)
GPSImgDirection
(撮影した画像の方向)
RATIONAL 1 45/2 (22.5)

XMPデータ

Photo Sphere XMPが記録されています。
XMPはExifと同様APP1セグメントで記録されますので、前述のマーカセグメントの項目で書きましたが、ExifとXMPを両方記録する場合は、APP1セグメントが2つになります。
XMPは、XMLを拡張したものとなっており、XMLパーサーやDOMパーサー等でパースすることが可能と思います。
サンプル画像の実際に記録されているPhoto Sphere XMPをそのまま記述すると以下のようになります(インデントは追加してます)。

http://ns.adobe.com/xap/1.0/
<?xpacket begin="(UTF-8 BOM 3バイト)" id="W5M0MpCehiHzreSzNTczkc9d"?>
  <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="RICOH THETA for iOS 1.0.0">
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description xmlns:GPano="http://ns.google.com/photos/1.0/panorama/" rdf:about="">
        <GPano:ProjectionType>equirectangular</GPano:ProjectionType>
        <GPano:UsePanoramaViewer>True</GPano:UsePanoramaViewer>
        <GPano:CroppedAreaImageWidthPixels>5376</GPano:CroppedAreaImageWidthPixels>
        <GPano:CroppedAreaImageHeightPixels>2688</GPano:CroppedAreaImageHeightPixels>
        <GPano:FullPanoWidthPixels>5376</GPano:FullPanoWidthPixels>
        <GPano:FullPanoHeightPixels>2688</GPano:FullPanoHeightPixels>
        <GPano:CroppedAreaLeftPixels>0</GPano:CroppedAreaLeftPixels>
        <GPano:CroppedAreaTopPixels>0</GPano:CroppedAreaTopPixels>
        <GPano:PoseHeadingDegrees>0.0</GPano:PoseHeadingDegrees>
        <GPano:PosePitchDegrees>0.0</GPano:PosePitchDegrees>
        <GPano:PoseRollDegrees>0.0</GPano:PoseRollDegrees>
      </rdf:Description>
    </rdf:RDF>
  </x:xmpmeta>
<?xpacket end="w"?>

一番最初のルートタグ?(xpacket)の外に書かれている"http://ns.adobe.com/xap/1.0/"(\0終端,計29バイト)はXMPの仕様において固定で記録しなければならないとされており、XMLパーサー等にかけるときはこの29バイトは除外してかけるようにします。
xpacketタグのbegin属性には、文字コードのBOMがバイナリーのまま記録されています。
このBOMによってXMPのエンコードおよびバイトオーダーをUTF-8,UTF-16BE,UTF-UTF-16LE,UTF-32BE,UTF-32LEの中から選択することが可能なのですが、
XMPの仕様においてJPEGにXMPを記録する場合はUTF-8にしなければならないとなっており、実際、サンプル画像のXMPもUTF-8(のBOM)となっていました。
ちなみに、id属性の"W5M0MpCehiHzreSzNTczkc9d"は仕様において固定で、この文字列でないといけないようです。

一応、サンプル画像のXMPデータを表にまとめると以下のようになります。

データ名
GPano:ProjectionType "equirectangular"
GPano:UsePanoramaViewer "True"
GPano:CroppedAreaImageWidthPixels 5376
GPano:CroppedAreaImageHeightPixels 2688
GPano:FullPanoWidthPixels 5376
GPano:FullPanoHeightPixels 2688
GPano:CroppedAreaLeftPixels 0
GPano:CroppedAreaTopPixels 0
GPano:PoseHeadingDegrees 0
GPano:PosePitchDegrees 0
GPano:PoseRollDegrees 0

1つ目のAPP13

APP13のセグメントは、ググってみるとPhotoShop資源データが記録されるとなっています。具体的なデータの意味は分らないため、16進数でデータを記述します。

データID(hex) 説明
0404 IPTC-NAA record Contains the File Info... (データなし)
0425 Caption digest 16 bytes: RSA Data Security, MD5 message-digest algorithm D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E

2つ目のAPP13

1つ目と同様で、1つ目とは違うデータIDのデータが記録されているのかと思いましたが、2つ目も値は違いますが同じデータIDのデータが記録されていました。

データID(hex) 説明
0404 IPTC-NAA record Contains the File Info... 1C 01 5A 00 03 1B 25 47 1C 02 00 00 02 00 02 1C 02 74 00 2D 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 1C 02 78 00 3F 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 00
0425 Caption digest 16 bytes: RSA Data Security, MD5 message-digest algorithm 15 F2 53 FB 69 9E 2C 71 D4 FD D4 21 05 ED 4D 36

最後に気になる点

セグメント構成

やはり、前述したようにセグメント構成がExif 2.3の規格には沿っていないと思われるところです。
この点は修正してほしいところです。

GPS

THETA S のスペックを見るとGPSは搭載されていません。
APIリファレンスの gpsInfoには、"クライアントより指定可能"と書かれており、スマホのアプリから撮影したときにスマホのGPS情報ををTHETA Sに送り撮影した画像に付加するといった感じの運用になるのかなと予想します。