PNG
PNG の行ごとのフィルタと Deflate の圧縮を、画像の上で 1 行ずつ追います。
見本
ファイル
PNG・JPEG・WebP など。この枠か画像の枠へドロップも可。再符号化は長い辺を 1024 画素まで
まだ選んでいません
対象
色の型
フィルタ
圧縮レベル
インターレース
- ファイルの大きさ
- —
- 1 画素あたり
- —
- 圧縮率
- —
- ブラウザの zlib
- —
- 文字
- —
- 一致
- —
- CRC-32 · Adler-32
- —
画像
ファイルの構成
| チャンク | 位置 | 長さ | 内容 | CRC-32 |
|---|
動作原理と式
符号化の手順
- 画素色の型・深度のバイトの並び
- Adam77 パスに並べ替え(選んだときだけ)
- フィルタ行ごとに予測との差
- DeflateLZ77 とハフマン符号
- zlibヘッダ 2 バイトと Adler-32
- チャンクIDAT に分けて CRC-32
PNG の圧縮は可逆です。フィルタは値を変えずに並びを圧縮しやすくし、Deflate が同じ並びの繰り返しと値の偏りを詰めます[1]。
チャンク
ファイルは 8 バイトの署名 89 50 4E 47 0D 0A 1A 0A と、チャンクの並びです[1]。
- 長さ4 バイト
- 種類英字 4 文字
- データ長さの分
- CRC-32種類とデータから
- IHDR: 幅・高さ・深度・色の型・インターレース
- PLTE: パレットの色(色の型 3)
- tRNS: パレットの不透明度か、透明にする 1 色
- IDAT: zlib のデータ。いくつに分けてもよい
- IEND: 終わり
- 種類の 1 文字目が小文字のチャンクは補助で、知らなければ読み飛ばしてよい
フィルタ
各行の先頭に種類 0〜4 のバイトを置き、行のバイト を予測との差 に置き換えます[1]。
- : 1 画素左の同じバイト(深度 8 未満は 1 バイト左)
- : 上の行の同じバイト
- : 左上
- 行の外と最初の行の上は 0。Adam7 ではパスの中の上の行
適応は差を符号付きのバイト とみなした絶対値の和が最小の種類を行ごとに選びます。仕様が勧める経験則で、libpng も同じです[1][5]。最小の大きさになるとは限りません。
Deflate
フィルタ後の行の並びを LZ77 とハフマン符号で詰めます[2]。
- LZ77: 32,768 バイト前までに同じ並びがあれば、長さ 3〜258 と距離 1〜32,768 の一致にする。なければ文字(1 バイト)
- 記号: 文字 0〜255・ブロックの終わり 256・長さの符号 257〜285 を 1 つの表、距離の符号 0〜29 を別の表で符号にする。長さと距離の端数は付加ビット
- ブロック: stored(そのまま)・固定の表・動的な表(表そのものを先頭に書く)の 3 種。符号の長さは 15 ビットまで
- ビットの順: バイトの下位ビットから詰める。ハフマン符号だけは符号の先頭のビットから詰める
一致の探し方と圧縮レベルは zlib の deflate.c の表にならいます。レベル 1〜3 はすぐに一致を採り、4 以上は次の位置の一致と比べてから決めます(遅延一致)[4]。復号では符号長の表と符号を puff.c と同じ水準で検査します[6]。
Adam7
8×8 の区画の画素を 7 つのパスに分け、粗い格子から送ります[1]。読み込みの途中でも全体の荒い絵が出せる代わりに、隣の画素が離れるのでフィルタと LZ77 が効きにくくなります。
| パス | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| 始まり (x, y) | 0, 0 | 4, 0 | 0, 4 | 2, 0 | 0, 2 | 1, 0 | 0, 1 |
| 間隔 (x, y) | 8, 8 | 8, 8 | 4, 8 | 4, 4 | 2, 4 | 2, 2 | 1, 2 |
CRC-32 と Adler-32
出典
- 署名・チャンク・色の型・フィルタ(9 章)・適応の選び方(12.7)・Adam7(8.1)・CRC-32(5.5・付録 D)W3C, Portable Network Graphics (PNG) Specification (Third Edition), W3C Recommendation, 2025-06-24
- Deflate の LZ77・ハフマン符号・ブロック・ビットの順P. Deutsch, RFC 1951: DEFLATE Compressed Data Format Specification version 1.3, 1996
- zlib のヘッダと Adler-32P. Deutsch, J.-L. Gailly, RFC 1950: ZLIB Compressed Data Format Specification version 3.3, 1996
- 圧縮レベルの表(configuration_table)、ハッシュの連鎖、遅延一致J.-L. Gailly, M. Adler, zlib 1.3.1, deflate.c
- 適応のフィルタの選び方libpng, pngwutil.c の png_write_find_filter
- 復号の検査の水準M. Adler, puff.c(zlib の contrib/puff)
このツールで決めたこと
- 見本は画素ごとの式と決まった種の乱数で描く。試験図の 5 つの段は、それぞれ Sub・Up・Paeth・Average・None で最も小さくなるように作った
- Deflate のブロックは記号 16,384 個ごとに区切り、stored・固定・動的のうち最も短いものを使う
- 残差の画像は 128 に差の 2 倍を足した灰色(RGB はチャンネルごと)。None は元のバイトのまま
- 1 画素あたりのビット数は、記号のビットを記号が作るバイトに等分して配る
- グレーは 0.299R + 0.587G + 0.114B を丸めた値
- ブラウザの zlib は CompressionStream の deflate で、同じフィルタ後の並びを圧縮した大きさ
- 符号化し直すときは長い辺を 1,024 画素まで、元のファイルのまま調べるのは 1,048,576 画素まで