読者です 読者をやめる 読者になる 読者になる

うな(。・ε・。)

Android, iOS, AppEngine まわりのめもめも

JPEGのヘッダーを探訪する

JPEGのバイナリフォーマットは案外シンプルで、けっこう簡単に分解することができます。

JPEGはKey-Valueデータの羅列です。 0xFFで始まる2バイトはマーカといい、一まとまりの値が格納されていることの印となっています。 例えば0xFF 0xDBの2バイトはDQTマーカといい、次のマーカまで続くデータ列をDQT(量子化テーブル)として解釈することができます。

JPEGにはこのような構造で、圧縮に使った情報(テーブル)と、画像の圧縮済みデータが格納されています。

圧縮に使った情報としては、DQT(量子化テーブル)DHT(ハフマンテーブル)が格納されており、両方とも伸長するためには不可欠です。 圧縮済みの実データはSOS(スキャンヘッダ)に続くデータ列に格納されています。

典型的なJPEGは次のような構造をしています。

マーカ マーカ名 意味
0xFF 0xD8 SOI JPEGファイルデータの開始
0xFF 0xDB DQT 量子化テーブル
0xFF 0xC0 SOF0 圧縮の種類や画像サイズなどの情報
0xFF 0xC4 DHT ハフマンテーブル
0xFF 0xDA SOS 画像データの開始
0xFF 0xD9 EOI JPEGファイルデータの終了

実例

# SOI - 画像データ開始

FF D8
# DQT - Define Quantization Table(s) http://hp.vector.co.jp/authors/VA032610/JPEGFormat/marker/DQT.htm
# 132 bytes

FF DB: 00 84 00 0D 09 0A 0B 0A 08 0D 0B 0A 0B 0E 0E 0D 0F 13 20 15 13 12 12 13 27 1C 1E 17 20 2E 29 31 30 2E 29 2D 2C 33 3A 4A 3E 33 36 46 37 2C 2D 40 57 41 46 4C 4E 52 53 52 32 3E 5A 61 5A 50 60 4A 51 52 4F 01 0E 0E 0E 13 11 13 26 15 15 26 4F 35 2D 35 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F 4F
# SOF0 - Start Of Frame (baseline) http://hp.vector.co.jp/authors/VA032610/JPEGFormat/marker/SOF.htm
# 17bytes

FF C0: 00 11 08 00 28 00 1E 03 01 22 00 02 11 01 03 11 01
# DHT - ハフマンテーブル定義 http://hp.vector.co.jp/authors/VA032610/JPEGFormat/marker/DHT.htm
# 418bytes

FF C4: 01 A2 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA 01 00 03 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA
# SOS - スキャンヘッダー http://hp.vector.co.jp/authors/VA032610/JPEGFormat/marker/SOS.htm

FF DA: 00 0C 03 01 00 02 11 03 11 00 3F 00 C0 9E C3 50 9F 54 9E 4B 16 91 22 75 52 C7 61 23 9E 0F 38 C0 3C 56 54 96 97 C2 47 F2 ED 5D A2 2C 76 E1 03 02 3B 7B D7 A4 F8 7A 28
FF 00 E1 13 9E E0 5D 3C AC 15 A5 66 60 06 70 0F 04 7B 55 0B 2B 75 16 F1 03 D9 40 FC 71 51 49 CA 4A CD EC 54 DA 4C E1 ED E3 9D 67 4C DA 15 C1 07 3E 41 1C FD 6A E7 8A EC 60 B2 86 C2 68 90 AC B3 40 AD 2A B1 38 2C DC E4 7A 74 AE E1 6D 40 20 80 6B 96 F8 96 71 A8 43 10 E8 8A AB F9 28 FF 00 E1 13 9E E0 5D 3C AC 15 A5 66 60 06 70 0F 04 7B 55 0B 2B 75 16 F1 03 D9 40 FC 71 51 49 CA 4A CD EC 54 DA 4C E1 ED E3 9D 67 4C DA 15 C1 07 3E 41 1C FD 6A E7 8A EC 60 B2 86 C2 68 90 AC B3 40 AD 2A B1 38 2C DC E4 7A 74 AE E1 6D 40 20 80 6B 96 F8 96 71 A8 43 10 E8 8A AB F9 28
FF 00 1A A6 E4 9D AF A0 2B 34 6B E9 57 46 2F 08 B5 B6 06 6E 56 48 C9 1E ED B6 B6 E1 8D 30 3F C2 B0 A7 86 2B 2B 4B 1B 75 66 28 24 EA 7A 9C 1C 9F E5 5A 76 F7 23 6A 65 D7 27 D5 48 A8 C3 6B 16 C5 5F E2 B1 6D 64 65 61 90 D8 3D 7E 5E 95 42 FA DA CF 56 BA B9 96 74 DC 04 E4 2E 47 A0 02 AC 7D A9 4A 02 0C 44 6E C7 0F 54 20 93 75 AB C8 38 DD 71 2F E8 D8 FE 95 18 BD 21 74 6B 84 5C D3 B1 47 5D B9 8E DE E2 C5 66 91 23 51 BC 82 DD 3F CF 34 FB 2B E8 A6 8C 32 CF 6E 58 8E 40 6C F3 58 FE 3F FF 00 59 67 F4 6A CF F0 FF 00 41 55 87 76 A4 88 AD F1 9D 73 7D A4 22 0F 32 29 36 B7 52 BD 45 41 65 6E F3 E9 11 B0 99 E3 6F 3A 52 76 74 39 62 6A D2 7D C5 A4 D2 7F E4 0D 1F FD 74 6F E6 6A 31 6E D0 46 D8 6F 8C
# 終端

FF D9

tips

DQTはqに依存

JPEGのqによって、DQTは画像によらず一意に決まります。

DHTはほとんど同一

ハフマン符号化の性質上、本来はエンコード時に画像データを解析して最適のハフマンテーブルを作るべきです。しかし、処理量が大きいため Standard Huffman Table としてGeneral Purposeに使えるハフマンテーブルがJPEGの標準として定義されています。

最適化したハフマンテーブルを使うオプションを明示的に指定しなければ、この標準ハフマンテーブルが使用されます。

ですから、大部分のJPEGはqにも画像にもよらずDHTは同一です。

参考文献