PNGイメージのデータ構造を知ってみる(1)
PNG(Portable Network Graphics)イメージのデータ構造がどうなっているのか調べてみた。
基本的なデータ構造
PNGイメージは最初の8バイトを除いてチャンクと呼ばれる構造で成り立っています。
名称 | サイズ | 説明 |
---|---|---|
PNGヘッダー | 8byte | PNGファイルであることを示す |
IHDRチャンク | 25byte | PNGイメージの基本情報 |
: | : | : |
IDATチャンク | Nbyte | 画像の実データ |
: | : | : |
IENDチャンク | 12byte | PNGファイルの終端を表す |
PNGヘッダー
PNGヘッダーはこれがPNGファイルであることを示すための情報で、常に0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
で固定されています。
読み込んだファイルがPNGファイルかどうかはここを見ればわかります。
それぞれの値には以下のような意味があります。
16進数 | ASCII文字 | 役割 |
---|---|---|
0x89 | ¥x89 | ASCII文字で表現できない値。テキストファイルとして間違えてロードされてしまう可能性を減らす |
0x50 | P | フォーマット名 |
0x4E | N | フォーマット名 |
0x47 | G | フォーマット名 |
0x0D | CR(Ctrl-M) | “改行文字"として解釈されてしまい、システムによって勝手に「\r」や「\n」に置き換えられたりしないかを検出するために利用される |
0x0A | LF(Ctrl-J) | “改行文字"として解釈されてしまい、システムによって勝手に「\r」や「\n」に置き換えられたりしないかを検出するために利用される |
0x1A | Ctrl-Z | Control-z文字。ファイルの中身をテキストとして読み出し表示させようとしたDOSコマンドを停止させる |
0x0A | LF(Ctrl-J) | “改行文字"として解釈されてしまい、システムによって勝手に「\r」や「\r\n」に置き換えられたりしないかを検出するために利用される |
チャンクの構造
名称 | サイズ | 説明 |
---|---|---|
Length | 4byte | データの長さ |
Chunk Type | 4byte | チャンクの種類を表す |
Chunk Data | Length byte | 実際のデータ |
CRC | 4byte | 巡回単調検査 |
Portable Network Graphicsというだけあってバイトオーダーはネットワークオーダー(ビックエンディアン)です。
LengthはChunk Data部分の長さを表します。 最小で 0 最大で 2^31 - 1 までの値を収められます。
Chank Typeはチャンクの種類を表します。アルファベット4文字のデータがここに格納されます。詳しい種類については後述します。
Chunk DataはLength が 0 ではない場合、チャンクの種類に関連したデータが、格納されます。
CRCはChank TypeとDataの部分をcrc32チェックサムアルゴリズムを使って算出される値です。
データに破損がないかをチェックするのに利用します。
チャンクの種類
チャンクには必須のものと必須ではない補助的なものがあります。
今回は必須チャンクについて解説しようと思います。
必須チャンク
IHDR
IHDRチャンクはPNGヘッダーの直後に必要
オフセット(サイズ) | 名称 | 役割,補足 |
---|---|---|
0x0000(4) | Length | Dataの長さを表す,長さは常に13 |
0x0004(4) | Chunk Type | Chankの種類を表す,ASCII文字でIHDR |
0x0008(4) | Chunk Data(width) | 画像の幅 |
0x000C(4) | 〃(height) | 画像の高さ |
0x0010(1) | 〃(bit depth) | ビット深度(有効な値は 1, 2, 4, 8, 16 だが、カラータイプにより使用できないものも出てくる)※ 詳細は下の「ビット深度とカラータイプの組み合わせ」参照 |
0x0011(1) | 〃(color type) | カラータイプ(有効な値は0, 2, 3, 4, 6)※ 詳細は下の「ビット深度とカラータイプの組み合わせ」参照 |
0x0012(1) | 〃(compression method) | 圧縮手法 |
0x0013(1) | 〃(filter method) | フィルター手法 |
0x0014(1) | 〃(interlace method) | インターレース手法 |
0x0015(4) | CRC | Chank TypeとChunk Dataをもとに計算される |
ビット深度とカラータイプの組み合わせ
カラータイプ | 利用できるビット深度 | 解釈 |
---|---|---|
0 | 1,2,4,8,16 | グレースケール画像それぞれのピクセルがグレースケールサンプルで構成されている |
2 | 8,16 | トゥルーカラー画像それぞれのピクセルがR,G,B値により構成されている |
3 | 1,2,4,8 | インデックスカラー画像それぞれのピクセルがパレットインデックスで構成されているPLTEチャンクが必須 |
4 | 8,16 | グレースケール+アルファ画像それぞれのピクセルがグレースケールサンプルとアルファ値で構成されている |
6 | 8,16 | トゥルーカラー+アルファ画像それぞれのピクセルがR,G,B,アルファ値で構成されている |
IPLT
カラーパレット情報
カラータイプがIHDRのカラータイプが3の時のみ必須。複数の設置はできない。
後述のIDATよりも前に設置する必要がある。
Chunk Dataの長さが3で割り切れない時は、エラーになります。
オフセット(サイズ) | 名称 | 役割,補足 |
---|---|---|
0x0000(4) | Length | Dataの長さを表す,長さは常3で割り切れる数 |
0x0004(4) | Chunk Type | Chankの種類を表す,ASCII文字でPLTE |
0x00(1) | Chunk Data | パレットNo.1 R 0-255 |
0x00(1) | 〃 | パレットNo.1 G 0-255 |
0x00(1) | 〃 | パレットNo.1 B 0-255 |
0x00(1) | 〃 | パレットNo.2 R |
0x00(1) | 〃 | パレットNo.2 G |
0x00(1) | 〃 | パレットNo.2 B |
: | : | : |
0x—-(4) | CRC | Chank TypeとChunk Dataをもとに計算される |
IDAT
画像の実データ
最低でも1つは設置する必要がある。複数設置する場合は連続して設置する。
IHDRとIENDの間に設置する。
オフセット(サイズ) | 名称 | 役割,補足 |
---|---|---|
0x0000(4) | Length | Dataの長さを表す |
0x0004(4) | Chunk Type | Chankの種類を表す,ASCII文字でPLTE |
0x0008(N) | Chunk Data | 実際のイメージデータ |
0x—-(4) | CRC | Chank TypeとChunk Dataをもとに計算される |
IEND
PNGファイルの終端を表すチャンクです。
常に同じ値です。
オフセット(サイズ) | 名称 | 役割,補足 |
---|---|---|
0x0000(4) | Length | Dataの長さを表す,長さは常に0 |
0x0004(4) | Chunk Type | Chankの種類を表す,ASCII文字でIEND |
0x0008(4) | CRC | Chank Typeのcrc値0xAE 0x42 0x60 0x82 で固定 |
このチャンクより先は読み込まれません。
今回はこの辺にして次回は補助チャンクについてまとめてみようと思います。