JPEG画像の「中身」は一体どうなっているのか?

JPEG画像の「中身」は一体どうなっているのか?

  • GIGAZINE
  • 更新日:2020/08/01
No image

JPEGは最も利用される画像圧縮形式のひとつですが、JPEGが画像をどのように圧縮し、コンピューターがどのようにJPEGデータを処理しているかは、JPEGという名称ほどは知られていません。そんなJPEGデータの構造について、Googleでセキュリティ監査に携わるangealbertini氏が説明しています。

formats/jpeg.md at master · corkami/formats · GitHub

https://github.com/corkami/formats/blob/master/image/jpeg.md

JPEGの正式名称は「Joint Photographic Experts Group」で、画像の圧縮形式のひとつです。ファイルを16進数のバイナリで表示するLinuxのコマンド「xxd」でJPEGを表示するとこんな感じ。ランダムな文字列が並んでいるように見えますが、バイナリの羅列には意味があります。

No image

JPEGは「データの種類」「データの長さ」「データそのもの」をセグメントというまとまりで保持しており、それらのセグメントが連なったシンプルな構造とのこと。データの種類はMarkerと呼ばれる部分で表され、「ff」というバイトにゼロでないバイトを続けて定義します。例えば、先ほどのバイナリの先頭に表示されていた「ffd8」は画像データの始まりを意味しており、「SOI」と呼ばれるMarkerであるとのこと。

No image

逆に、バイナリの最後には画像データの終わりを意味する「EOI」Markerである「ffd9」が表示されています。

No image

ほとんどのJPEGファイルのバイナリは「FF D8 FF E0 00 10 .J .F .I .F 00」というパターンから始まるとangealbertini氏。SOIである「FFD8」の次には「Application 0(APP0)」と呼ばれる予約領域があり、「FFE0」というMarkerから始まります。APP0領域には「JFIF」といった識別子や解像度などの情報が保存されているとのこと。

No image

APP0領域の次に存在するのが「量子化テーブル」で「FFDB」というMarkerで表されます。JPEG画像は8×8ドットのブロックに分けられ、それぞれのブロックにおける輝度や色差などは座標軸上で波形として表現されています。この波形は離散コサイン変換と呼ばれる計算によって細部が単純化されますが、単純化された後のデータの端数を切り捨て、さらにデータを圧縮するために利用するのが量子化テーブルです。量子化テーブルでは画質などを操作することができ、切り捨てる端数が大きければ大きいほど、JPEG変換後の画質が粗くなります。JPEGが非可逆圧縮であるのは、このとき数値の端数が切り捨てられてしまうのが理由というわけ。

No image

量子化テーブル後には「START OF FRAME(SOF)」があり「FFC0」などのMarkerで表します。SOFでは画像のサイズなどが定義されているとのこと。

No image

「FFC4」というMarkerで始まる「ハフマンテーブル」は、データをさらに圧縮するためのハフマン符号化を行うための領域です。ハフマン符号は、データを出現頻度によって分類した上で、出現頻度の低いデータを0と1で枝分かれするバイナリツリーの深部に配置し、バイナリツリーの先頭から符号化することでデータを圧縮することができるアルゴリズム。JPEGでは量子化とハフマン符号化の2段階の圧縮行程があるというわけです。

No image

「START OF SCAN」や「IMAGE DATA」には、画像データの成分情報や画像データそのものが保存されています。

No image

JPEG画像を構成するバイナリの全体像はこんな感じ。画像ソフトはMarkerなどを頼りにデータを読み込むことで、JPEG画像を表示することが可能となっています。

No image

この記事をお届けした
グノシーの最新ニュース情報を、

でも最新ニュース情報をお届けしています。

外部リンク

  • このエントリーをはてなブックマークに追加