PNG形式の例でアルゴリズムを圧縮する



次の実験室作業の一環として、同僚と私は16進ダンプファイルPNGを解析するタスクに直面しました。 RFC 2083標準によれば、PNG形式には、 Deflateアルゴリズムによって圧縮されたピクセルデータが格納されます 。 したがって、ダンプを解析するときは、Inflateアルゴリズムを使用して圧縮データを解凍する必要がありました。

分析は、次の4x4ピクセル画像で実行されます。



Deflate標準RFC 1951を使用して圧縮されたデータストリームは、 RFC 1950標準のzlib形式でPNGに格納されます。この標準を解析に使用します。 zlibヘッダーは、Deflate設定を定義します。 次の構造になっています。
1バイト
1バイト
4バイト
CMF
Flg
独裁者
4ビット
4ビット
2ビット
1ビット
5ビット
シンフォ
SM
FLEVEL
フィクション
Fcheck

フィールドの詳細:


DICTの後に(FDICTがインストールされている場合)、圧縮データのストリームがあり、PNGの長さはIDAT構造体のCHUNK_LENGTHフィールドに依存します。 zlibバッチの最後には、Adler-32アルゴリズムを使用して非圧縮データから計算されたADLER-32チェックサムがあります。

この場合、zlibヘッダーは次のようになります。
78 DA
0111
1000
11
0
11010
ウィンドウサイズ= 32K
圧縮方法=収縮
圧縮レベル=最速
辞書が使用されている= false
チェックビット

ヘッダーから、辞書が使用されていないことがわかります(FDICT = 0)。

画像の圧縮データ:

63 F8 3F 93 E1 3F 03 C3 CC FF 20 1A C8 00 22 24 0E 58 12 85 33 D3 F8 3F 03 32 07 44 03 00 AA 05 23 77

その後、ビットはバイト単位で連続して読み取られます。 バイトでは、最後のビットから最初のビットに移動します(たとえば、データストリームで2バイトが連続して移動する場合:63 F8(0b01100011 0b11111000)。次のビットシーケンスを取得する必要があります:1100011000011111)。

読み取りシーケンスの最初のビットはBFINALフラグで、このデータが最後かどうかを示します。 次の2つのBTYPEビットは、圧縮のタイプを示します。00-圧縮なし、01-固定ハフマンコードによる圧縮、10-動的ハフマンコードによる圧縮、11-値は予約済みです。

固定ハフマンコードの表:
アンパック値
ビット数
コード
拠点
0〜143
8
00110000から10111111
00110000
144〜255
9
110010000から111111111
110010000
256〜279
7
0000000から0010111
0000000
280〜287
8
11000000から11000111
11000000

オフセット表:
コード
追加します。 ビット
距離
コード
追加します。 ビット
距離
コード
追加します。 ビット
距離
0
0
1
10
4
33〜48
20
9
1025〜1536
1
0
2
11
4
49〜64
21
9
1537 2048
2
0
3
12
5
65〜96
22
10
2049〜3072
3
0
4
13
5
97〜128
23
10
3073〜4096
4
1
5、6
14
6
129〜192
24
11
4097-6144
5
1
7、8
15
6
193〜256
25
11
6145-8192
6
2
9-12
16
7
257〜384
26
12
8193-12288
7
2
13〜16
17
7
385〜512
27
12
12289-16384
8
3
17-24
18
8
513-768
28
13
16385-24576
9
3
25〜32
19
8
769-1024
29日
13
24577-32768

長さ表:
コード
追加します。 ビット
長さ
コード
追加します。 ビット
長さ
コード
追加します。 ビット
長さ
257
0
3
267
1
15、16
277
4
67〜82
258
0
4
268
1
17、18
278
4
83〜98
259
0
5
269
2
19〜22
279
4
99〜114
260
0
6
270
2
23〜26
280
4
115〜130
261
0
7
271
2
27〜30
281
5
131〜162
262
0
8
272
2
31〜34
282
5
163〜194
263
0
9
273
3
35〜42
283
5
195〜226
264
0
10
274
3
43〜50
284
5
227〜257
265
1
11、12
275
3
51〜58
285
0
258
266
1
13、14
276
3
59〜66




展開するとき、データは2つのタイプで表すことができます:固定値と逆バイアスの長さ。

読み取ったデータは、固定値に変換する必要があります。 以下は変換式です。

lit value = data-base + left bound、ここで
点灯値-固定値、
base-表1の列
左境界-表1のアンパックされた値の列の左の数値。

データを読み取るとき、各間隔のプレフィックスが異なるという事実に対応するテーブル1の固定値の間隔を明確に決定できます。

たとえば、シーケンスから2バイトのF8と3Fを選択してみましょう。 000 111111111 1100であることが判明したビットシーケンス。現在の読み取り位置を4とし、7ビット(最小ビット数)を読み取ると、間隔2に対応するプレフィックス1111111が得られます。これから、読み取りコードの長さは9になります。

0b111111111 = 0d511

上記の式を使用すると、エンコードされた数値は255 = 511-400(0b110010000)+ 144であることがわかります。

データストリームに固定値ではなく、長さと逆バイアスに関する情報が含まれている場合、つまり 読み取られた値は3番目の間隔になります。 このバージョンでは、これはサブシーケンスになります。

20 1A C8( 0000010 0 01011000 00010011)。

間隔3に入る最初の7ビット(0b0000010)を読み取ります。式により、数値に変換します。 これは、257 = 1-0 + 256の数になります。次に、表3を使用します。コード257は、考慮する必要がある追加ビットの数が0であることを示します。3列目の長さは3です。 。 これらのビットは、長さに追加する数値を決定します。

次に、5ビット(0b00101 = 0d5)を読み取り、逆バイアスを決定します。 私たちの場合、これは5です。表2から、追加の1ビットを読み取る必要があることは明らかです。 逆順で読みます。 1(0d1)になりました。 この数値を列3からの最小距離に追加します。そして、逆バイアスは7 + 1 = 8になります。

これはどういう意味ですか? たとえば、0 255 153 0 255 0 0 153 255の9つの値をカウントしました。戻り距離は、このストリームに戻す必要がある値の数を示します。つまり、 2番目の値-255になります。3に等しい長さは、データストリームから3つの値を取得する必要があることを示しています。 255 1530。長さがオフセットより大きい場合、開始位置に戻り、長さに等しい値の数をカウントするまで元の順序で再度読み取ります。 長さが7で、逆バイアスが2であるとします。2つの値でシフトされます。 最後から2番目の数字の位置は153です。判明したシーケンスは153 255 153 255 153 255 153です。最終的に、アンパッカーはゼロに等しい次の固定値を読み取ると、作業を終了します。

完全なダンプ分析:
01100 01 1ファイナルチャンク、固定ハフマン
11111 000 48-48 + 0 = 0-フィルター:なし
0011 1111 511-400 + 144 = 255
100 10011 409-400 + 144 = 153
111 00001 48-48 + 0 = 0
00 111111 511-400 + 144 = 255
00 000011 48-48 + 0 = 0
11 000011 48-48 + 0 = 0
1 1001100 409-400 + 144 = 153
11111111 511-400 + 144 = 255
0 0 100 000 2-0 + 256 = 258長さ= 4
000 1 1010 5距離= 7 + 1 = 8
1100 1000 1-0 + 256 = 257長さ= 3
00000 00 0 6距離= 9 + 0 = 9
0 01000 01 1-0 + 256 = 257長さ= 3、2距離= 3
0 0100100 9-0 + 256 = 265長さ= 11 + 0 = 11
00 00 1110 7距離= 13 + 0 = 13
010 11000 3-0 + 256 = 259長さ= 5
000100 10 9距離= 25 + 4 = 29
100 0 0101 10-0 + 256 = 266長さ= 13 + 0 = 13
0011 00 11 7距離= 13 + 0 = 13
110 10011 409-400 + 144 = 153
111 11000 99-48 + 0 = 51
00 111111 511-400 + 144 = 255
00 000011 48-48 + 0 = 0
00 1 10010 9-0 + 256 = 265長さ= 11 + 1 = 12
000 00 111 7距離= 13 + 0 = 13
0100 0100 2-0 + 256 = 258長さ= 4
000000 1 1 5 DISTANCE = 7 + 1 = 8
0000000 0 0-0 + 256 = 256 END
10101010 ADLER
00000101 ADLER
00100011 ADLER
01110111 ADLER
0
255153 0 255
0 0 153 255
255153 0 255
255 0 0 255
0
0 0 153 255
255153 0 255
255 0 0 255
255153 0 255
0
255153 0 255
255 0 0 255
255153 0 255
0 153 51 255
0
255 0 0 255
255153 0 255
0 153 51 255
255153 0 255

同様の材料の検索は、最終的に標準につながりました。 この記事が、彼らの母国語で理解しやすいロシア語での努力を必要としている人々の助けになることを願っています。

ソース画像

Source: https://habr.com/ru/post/J274825/


All Articles