/
628.txt
572 lines (437 loc) · 28.4 KB
/
628.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
[148] [DFN[DELFATE]] は、[[圧縮形式]]の1つです。非常によく用いられています。
* 仕様書
[152] [[deflate][DEFLATE]] は [DFN[RFC 1951]] により定義されています。
[REFS[
- [5] '''[CITE@en[RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3]] ([TIME[2016-01-10 18:30:17 +09:00]] 版) <https://tools.ietf.org/html/rfc1951>'''
-- [7] [CITE@en[RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3]] ([TIME[2016-01-10 18:30:17 +09:00]] 版) <https://tools.ietf.org/html/rfc1951#section-1>
-- [25] [CITE@en[RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3]] ([TIME[2016-07-03 09:57:20 +09:00]]) <https://tools.ietf.org/html/rfc1951#section-2>
-- [26] [CITE@en[RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3]] ([TIME[2016-07-03 09:57:20 +09:00]]) <https://tools.ietf.org/html/rfc1951#section-3>
-- [116] [CITE@en[RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3]] ([TIME[2017-09-17 17:36:41 +09:00]]) <https://tools.ietf.org/html/rfc1951#section-4>
]REFS]
* データ形式
[124] [[RFC 1591]] は、
[[圧縮]]された [[DEFLATE]] データのことを[[圧縮データ集合]]と呼んでおり、
[[圧縮]]の前の元のデータのことを[DFN[[RUBYB[入力データ]@en[input data]]]]
[SRC[>>25]] と呼んでいます。
[12] [[DEFLATE]] の処理において[[入力データ]]は[[ブロック]]の連なり [SRC[>>25]]
と解釈されます。また[DFN[[RUBYB[圧縮データ集合]@en[compressed data set]]]]は、
[[ブロック]]の[[系列]]です [SRC[>>25]]。
[[入力データ]]の[[ブロック]]を処理したものが、
それぞれ順に[[圧縮データ集合]]の[[ブロック]]となります。
-*-*-
[8] [RUBYB[[[圧縮器]]]@en[compressor]]は、
[[仕様]]にすべて従うデータ集合を生成しなければなりません [SRC[>>7]]。
[6] [RUBYB[[[展開器]]]@en[decompressor]]は、
特に定める場合を除き、
[[仕様]]に[[適合]]する任意のデータ集合を[[受理]]し[RUBYB[[[展開]]]@en[decompress]]できなければなりません。 [SRC[>>7]]
** ビット列の表現
[27] [[DEFLATE]] の出力は[[バイト列]]です。
[[バイト]]内の[[ビット順]]は規定されておらず [SRC[>>26]]、
[[プラットフォーム]]や[[プロトコル]]に依存します。
[29] [[多バイト]]の値は、重みの小さな[[バイト]]から順に並べた[[バイト列]]
[SRC[>>26]] ([[小エンディアン]]) とします。
[28] [RUBYB[データ要素]@en[data element]]を[[バイト列]]にする際には、
[[バイト]]の重みの小さな[[ビット]] ([[LSB]]) から順に詰めていきます。 [SRC[>>26]]
[30] [[ハフマン符号]]''以外''のデータ要素は、
当該データ要素の LSB から順に詰めていきます。 [SRC[>>26]]
[31] [[ハフマン符号]]は、重みの大きな[[ビット]] ([[MSB]])
から順に詰めていきます。 [SRC[>>26]]
** ブロック
[62] [[入力データ]]の[RUBYB[ブロック]@en[block]]の大きさは任意に決められますが、
[N[65535]] [[バイト]][[以下]]でなければなりません。[SRC[>>25]]
圧縮器は、[[ブロック]]の最大長を制限できます。
しかし展開器は、任意の長さを扱えなければなりません。 [SRC[>>26]]
[63] [[圧縮データ集合]]の[RUBYB[ブロック]@en[block]]は、
入力データの各[[ブロック]]に対応します。 [SRC[>>25]]
[66] なお[[ブロック]]境界と[[バイト]]境界は一致しないかもしれません。 [SRC[>>26]]
-*-*-
[64] [[圧縮データ集合]]の各[[ブロック]]は、3ビットのヘッダーから始まります。 [SRC[>>26]]
[65] 第1ビット [DFN[[VAR[BFINAL]]]] は、
それが[[圧縮データ集合]]の最後の[[ブロック]]かどうかを表します。
ビットが設定されていれば、最後です。 [SRC[>>26]]
[132] 最終[[ブロック]]後に更に[[ビット列]]が続く時、それをどう処理するべきかは、不明です。
[67] 第2ビットと第3ビットの [DFN[[VAR[BTYPE]]]] は、圧縮方法を表します。 [SRC[>>26]]
[142] 展開器に与えられたデータが3ビットに満たない時、どう解釈するべきかは不明ですが、
壊れた入力と扱うのが自然でしょう。
*** 無圧縮ブロック
[133] [VAR[BTYPE]] が [N[00[SUB[2]]][0b00]] の時、
無圧縮を表します。 [SRC[>>26]]
[134] [[ヘッダー]]を含む[[バイト]]の残りの[[ビット]]は、あっても無視します。 [SRC[>>26]]
[135] その次の2バイトは、 [CODE[LEN]] と呼び、この[[ブロック]]のデータのバイト数を表します。
[SRC[>>26]]
[136] その次の2バイトは、[CODE[NLEN]] と呼び、 [CODE[LEN]] の[[1の補数]]とします。
[SRC[>>26]]
[137] その次の [VAR[LEN]] バイト分が、この[[ブロック]]の[[リテラル]]データとします。
[SRC[>>26]]
[138] [VAR[LEN]] と [VAR[NLEN]] が整合しない時、どう処理するべきかは、不明です。
[145] 展開器に与えられたデータが指定された長さに満たない時、どう処理するべきかは不明です。
*** 圧縮ブロック
[139] [VAR[BTYPE]] が
[N[01[SUB[2]]][0b01]] のとき、[[固定ハフマン符号]]圧縮 (>>106) を表します。 [SRC[>>26]]
[140] [VAR[BTYPE]] が [N[10[SUB[2]]][0b10]] のとき、
[[動的ハフマン符号]]圧縮 (>>113) を表します。 [SRC[>>26]]
-*-*-
[20] [[ブロック]]の[DFN[[RUBYB[[[圧縮されたデータ部分]]]@en[compressed data part]]]]は、
[[要素]]の[[系列]]です。各[[要素]]は、
[RUBYB[リテラルバイト群]@en[literal bytes]]か、
[RUBYB[重複列への指示子]@en[pointer to duplicated strings]]かのいずれかです。 [SRC[>>25]]
[21] 重複列への指示子は、
[RUBYB[長さ]@en[length]]と[RUBYB[前方向の距離]@en[backward distance]]との組です。 [SRC[>>25]]
[22] [[長さ]]は、 258 バイト[[以下]]です。 [SRC[>>25]]
[17] [[距離]]は、 32KB [[以下]]です。すなわち、[[指示子]]は、[[入力データ]]の
32KB 前までの[[ブロック]]の[RUBYB[列]@en[string]]を参照できます。 [SRC[>>25]]
圧縮器は、より小さな距離を上限としても構いません。
しかし展開器は、 32KB まで処理できなければなりません。 [SRC[>>26]]
[146] [[指示子]]は、[[入力データ]]の[[ブロック]]の境界をまたがることができます
[SRC[>>25]]。しかし[[入力データ]]の先頭より前を指すことはできません [SRC[>>25]]。
[[入力データ]]の先頭より前の[[指示子]]が与えられた時、どう処理するべきかは不明です。
[157] [[距離]]の上限は、
[[圧縮]]器や[[展開]]器が探索のために保持しておかなければならない[[バッファー]]や[[リスト]]
(>>129) のサイズに影響します。 [[DEFLATE]] を用いる[[プロトコル]]は、
これを制限したり、制限を記述できたりする場合があります。
;; [[LZ77 sliding window]] 参照。
[23] [[リテラル]]と[[長さ]]は、その[[ブロック]]の[[リテラル・長さ符号]]により[[符号化]]します。
[[距離]]は、その[[ブロック]]の[[距離符号]]により[[符号化]]します。
[147] 不正な[[符号]]が現れたときにどう処理するべきかは不明です。
[16] 各[[ブロック]]の[[ハフマン木]]は、互いに独立です。 [SRC[>>25]]
*** 予約
[141] [VAR[BTYPE]] の値 [N[11[SUB[2]]][0b11]] は、予約 (誤り) とされています。
[SRC[>>26]]
[14] [N[11[SUB[2]]][0b11]] が出現した時、これをどう処理するべきかは、不明です。
** ハフマン符号化
[32] [RUBYB[接頭辞符号化]@en[prefix coding]]は、
事前に与えられた[RUBYB[字母]@en[alphabet]]の[RUBYB[記号]@en[symbol]]を、
ビット列 (符号) として表現するものです。ここで、ビット列は記号ごとに長さが異なりますが、
構文解析器が常に曖昧無く記号を認識できるようにします。 [SRC[>>26]]
[33] 接頭辞符号は、[[二分木]]を使って定義します。
[[枝]]が [N[0]] または [N[1]] のいずれかを表すこととします。
[[枝]]がいずれかの[[記号]]を表すこととします。
[[根]]から[[葉]]までの[[枝]]の値を順番に並べたものが、[[符号]]を表します。 [SRC[>>26]]
[35] 構文解析器は、[[二分木]]の[[根]]から順に入力の[[ビット]]に従い進むことで、
記号を得ることができます。 [SRC[>>26]]
[EG[
[34] 次の[[木]]は、次の表のような[[符号]]を表しています。
[PRE[
/\
0 1
/ \
B /\
0 1
/ \
A /\
0 1
/ \
C D
]PRE]
,* 記号 ,* 符号
, A , [CODE[10]]
, B , [CODE[0]]
, C , [CODE[110]]
, D , [CODE[111]]
]EG]
[36] [[ハフマン算法]]により、[[字母]]とその[[頻度]]から最適な接頭辞符号を得られます。
頻度が高いほど身近な[[符号]]となります。これを[[ハフマン符号]]といいます。 [SRC[>>26]]
;; [37] ただし [[DEFLATE]] では[[符号]]長の上限があるので、少し複雑になります。 [SRC[>>26]]
[38] [[DEFLATE]] では次の2つの制限があります [SRC[>>26]]。
[FIG(list)[
- [39] ある[[ビット長]]のすべての[[符号]]は、
その表現する[RUBYB[[[記号]]]@en[symbol]]と同じ順序で[RUBYB[[[辞書的]]]@en[lexicographically]]に連続した値となっていること。
- [40] 短い[[符号]]が、長い[[符号]]よりも辞書的に前にあること。
]FIG]
[42] この制限を設けることで、[[記号]]に対応する[[ビット長]]
([DFN[[RUBYB[符号長]@en[code length]]]]) の[[リスト]]を示すだけで、
[[符号]]を記述できます [SRC[>>26]]。
[EG[
[41] 先程の例 (>>34) では、[[符号]]は [CODE[0]] < [CODE[10]] < [CODE[110]] = [CODE[111]]
と[[符号]]の長さの順が[[符号]]の順序と一致しています (>>40)。
また C < D と[[記号]]の順序と同じ長さの[[符号]]の順序が一致しています。
[43] [[記号]]群 (A, B, C, D) を表すこの[[符号]]群は、
各[[符号]]の[[ビット長]]から (2, 1, 3, 3) と表すことができます。
(この[[ビット長]]の組によって表される[[符号]]は一意に定まります。)
]EG]
[44] [VAR[N]] 個の[[記号]]について、[[符号長]]の[[リスト]][VAR[長さ群]]から、
対応する[[符号]]を [VAR[n]] [[ビット]]の[[整数]]の[[リスト]]として得るには、
次のようにします。 [SRC[>>26]]
[FIG(steps)[
= [45] [VAR[符号群]]を、[[空リスト]]に設定します。
= [46] [VAR[個数群]]を、[[空リスト]]に設定します。
= [49] [ [N[0]], [VAR[n]] ] の各[VAR[長さ]]について、
== [50] [VAR[個数群]] [ [VAR[長さ]] ] を、 [N[0]] に設定します。
= [47] [VAR[長さ群]]の各[VAR[長さ]]について、
== [48] [VAR[個数群]] [ [VAR[長さ]] ] を、 [N[1]] [[インクリメント]]します。
= [51] [VAR[符号]]を、 [N[0]] に設定します。
= [55] [VAR[次符号群]]を、[[空リスト]]に設定します。
= [52] [ [N[1]], [VAR[n]] ] の各[VAR[長さ]]について、順に、
== [53] [VAR[符号]]を、 ([VAR[符号]] + [VAR[個数群]] [ [VAR[長さ]] - 1 ]) [[<<]] 1 に設定します。
== [54] [VAR[次符号群]] [ [VAR[長さ]] ] を、[VAR[符号]]に設定します。
= [56] [ [N[0]], [VAR[N]] ] の各[VAR[記号]]について、
== [57] [VAR[長さ]]を、[VAR[長さ群]] [ [VAR[記号]] ] に設定します。
== [58] [VAR[長さ]]が [N[0]] 以外なら、
=== [59] [VAR[符号群]] [ [VAR[記号]] ] を、[VAR[次符号群]] [ [VAR[長さ]] ] に設定します。
=== [60] [VAR[次符号群]] [ [VAR[長さ]] ] を [N[1]] [[インクリメント]]します。
= [61] [VAR[符号群]]を返します。
]FIG]
** ブロックで用いるハフマン符号の記号
[102] 符号化された[[ブロック]]では、2種類の[[ハフマン符号]]を使います。
[118] [[DEFLATE]] の[[ハフマン符号]]は、
実際の各[[符号]]の直後に、
いくつかの[RUBYB[余剰ビット群]@en[extra bits]]が続く場合があります。
[101] [[余剰ビット群]]は、 [[MSB]] から順に並べたものと解釈します。 [SRC[>>26]]
-*-*-
[117] 1つ目の[[ハフマン符号]]は、
[[リテラル]][[バイト]] (実際に表したいデータの[[バイト]])
や[[長さ]]を表すもので、
[DFN[[RUBYB[リテラル・長さ符号]@en[literal/length code]]]] [SRC[>>26]]
([[字母]]は
[DFN[[RUBYB[リテラル・長さ字母]@en[literal/length alphabet]]]] [SRC[>>26]])
のような呼ばれ方をしています。
[103] [[リテラル・長さ符号]]では、
次のように[[記号]]の意味を設定します。 [SRC[>>26]]
[FIG(list)[
- [ [N[0]], [N[255]] ] - [[リテラル]]な[[バイト]]
- [N[256]] - [RUBYB[ブロック末]@en[end-of-block]]
- [ [N[257]], [N[285]] ] - 長さ
]FIG]
[100] 長さの指定の場合には、続く[[余剰ビット群]]によって実際の長さを求めます。 [SRC[>>26]]
[FIG[
[PRE[
Extra Extra Extra
Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
---- ---- ------ ---- ---- ------- ---- ---- -------
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
]PRE]
]FIG]
-*-*-
[119] 2つ目の[[ハフマン符号]]は、[[距離]]を表すものです。
[104] [[距離]]の[[符号]]でも、同様に余剰ビット群によって実際の[[距離]]の値を求めます。
[SRC[>>26]]
[FIG[
[PRE[
Extra Extra Extra
Code Bits Dist Code Bits Dist Code Bits Distance
---- ---- ---- ---- ---- ------ ---- ---- --------
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
]PRE]
]FIG]
** 固定ハフマン符号
[106] [VAR[BTYPE]] [N[01[SUB[2]]][0b01]] の[[ブロック]]の[[圧縮されたデータ部分]]は、
[DFN[[RUBYB[固定ハフマン符号]@en[fixed Huffman code]]]]を用いて[[符号化]]したデータです。
[120] [[固定ハフマン符号]]ブロックの[[リテラル・長さ符号]]は、
次のような[[符号長]]の持つ[[ハフマン符号]]とします。 [SRC[>>26]]
- [ [N[0]], [N[143]] ] - 8ビット
- [ [N[144]], [N[255]] ] - 9ビット
- [ [N[256]], [N[279]] ] - 7ビット
- [ [N[280]], [N[287]] ] - 8ビット
;; [107] ただし、 [N[286]] と [N[287]] は実際には使われません。 [SRC[>>26]]
[108] [[固定ハフマン符号]]の[[距離符号]] [ [N[0]], [N[31]] ] は、
そのまま5ビット固定長 (+ [[余剰ビット群]]) で表します。 [SRC[>>26]]
;; [109] [N[30]] と [N[31]] は実際には使われません。 [SRC[>>26]]
[24] [[圧縮されたデータ部分]]の末端は、 [N[256]] により表されます。
これが現れないで与えられたデータが終了した時[[展開器]]がどう処理するべきかは不明です。
** 動的ハフマン符号
[113] [VAR[BTYPE]] [N[10[SUB[2]]][0b10]] の[[ブロック]]の[[圧縮されたデータ部分]]は、
[DFN[[RUBYB[動的ハフマン符号]@en[dynamic Huffman code]]]]の[[ハフマン木]]と、
それを用いて[[符号化]]したデータです。
[122] [[動的ハフマン符号]]の[[ブロック]]は、次のもので構成されます [SRC[>>26]]。
[FIG(list members)[
: 5ビット ([VAR[HLIT]]) :
[[リテラル・長さ符号]]の数 - [N[257]]
: 5ビット ([VAR[HDIST]]) :
[[距離符号]]の数 - [N[1]]
: 4ビット ([VAR[HCLEN]]) :
符号長符号の数 - [N[4]]
: (([VAR[HCLEN]] + 4) × 3) ビット :
符号長字母の符号長を
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
の順に並べたもの。
各符号長は3ビット整数で表す。
: ([VAR[HLIT]] + [VAR[HDIST]] + [N[258]]) ビット :
次のもの:
[FIG(list members)[
: ([VAR[HLIT]] + [N[257]]) ビット :
[[リテラル・長さ符号]]の[[字母]]ごとの符号長を並べたもの。
: ([VAR[HDIST]] + [N[1]]) :
[[距離符号]]の[[字母]]ごとの符号長を並べたもの。
]FIG]
[[符号長符号]]で符号化する。[[リテラル・長さ符号]]部分と[[距離符号]]部分の境界をまたがって[[符号化]]される場合もある。
: 任意長 :
[[リテラル・長さ符号]]および[[距離符号]]により圧縮されたデータ
(末端は [N[256]])
]FIG]
[123] 使用する[[ハフマン符号]]の[[ハフマン木]]は、
その[[符号長]]の[[リスト]]として記述します。
[[符号長]]は、次の[[字母]]を持つ[[ハフマン符号]]
([DFN[[RUBYB[符号長符号]@en[code length code]]]]) によって記述します [SRC[>>26]]。
- [N[0]] - [N[15]] : 符号長 [N[0]] - [N[15]]
- [N[16]] :
前の符号長を、([[余剰ビット群]]2ビット + [N[3]]) 回複製する
[EG[
([N[8]], [N[16]], [N[11[SUB[2]]][0b11]], [N[16]], [N[10[SUB[2]]][0b10]]) は、
([N[8]], [N[8]], [N[8]], [N[8]], [N[8]], [N[8]], [N[8]],
[N[8]], [N[8]], [N[8]], [N[8]], [N[8]], [N[8]]) を表します。
]EG]
- [N[17]] :
符号長 [N[0]] を、 ([[余剰ビット群]]3ビット + [N[3]]) 回繰り返す
- [N[18]] :
符号長 [N[0]] を、 ([[余剰ビット群]]7ビット + [N[10]]) 回繰り返す
[114] ここで、[[符号長]] [N[0]] は、
該当する[[記号]]が[[字母]]に現れないため、
ハフマン符号構築アルゴリズムで省くべきことを示します。 [SRC[>>26]]
[115] [[距離符号]]が1つだけしか使われない場合には、
1ビットのみを使って符号化し、
0ビットは使いません。
この場合、符号長が1つと未使用の符号が1つとなります。
0ビットの符号1つの場合は、距離符号を使わない (すべてのデータがリテラルである)
ことを表します。 [SRC[>>26]]
[19] [[展開器]]に与えられたデータが記述された長さと矛盾する時、
どう処理するべきかは不明です。
[121] 末端に [N[256]] が現れないで与えられたデータが終了した時[[展開器]]がどう処理するべきかは不明です。
* 辞書
[149] 入出力データの先頭に「[[preset dictionary]]」を置くことが [[DEFLATE]] では想定されており
[SRC[>>26]]、 [[zlib]] では[[応用]]次第で利用できることになっています。
[[preset dictionary]] は、出現頻度の高いデータを予め送受信者間で共有することで、
指示子によって参照できるようにするものです。
[150] [[圧縮器]]は、 [[preset dictionary]] の[[バイト列]]を[[入力データ]]の初期状態として処理を開始し、
本来の無圧縮データをその続きの[[入力データ]]として用います。
[151] [[展開器]]は、
[[preset dictionary]] の[[バイト列]]を復号済みの[[入力データ]]の初期状態として処理を開始し、
復号済み[[入力データ]]のその続きの部分に本来の無圧縮データを得ます。
* 継続
[158] [[WebSocket]] [CODE[permessage-deflate]] では、
連続した[[メッセージ][WebSocketメッセージ]]の送信で前の[[メッセージ][WebSocketメッセージ]]の
[[LZ77移動窓]]を再利用することができ、
これを [[use context takeover]] と呼んでいます。
[159] 直前の[[メッセージ][WebSocketメッセージ]]を [[preset dictionary]]
として用いるようなものとも言えます。
* 符号化 (圧縮)
[127] [[RFC 1951]] は [[DEFLATE]] データ形式を定義していますが、
[[圧縮アルゴリズム]]自体は定めないこととしています。
しかし [[DEFLATE]] 形式は [[LZ77]] により[[圧縮]]することを想定したものであり、
[RUBYB[強く推奨]@en[strongly recommended]]される、
[[特許]]問題が無いと考えられる[[算法]]が示されています。
もちろん、それ以外の方法により生成することも認められています。 [SRC[>>116]]
[128] 圧縮器は、
新しいハフマン木が有用と考えられる時や、
ブロックサイズが圧縮木のブロックバッファーの末尾に達した時、
ブロックを終えます。 [SRC[>>116]]
[129] 圧縮器は、
重複する[[文字列]]を探すため、
3バイトの列に対する[[ハッシュ関数]]を使った[RUBYB[連鎖ハッシュ表]@en[chained hash table]]を使います。
入力の次の3バイトがハッシュ表にあれば、
該当するハッシュ鎖のすべての文字列のうち最長一致のものを選択します。
ハッシュ表にない場合は、リテラルバイトとしてそのまま出力します。 [SRC[>>116]]
[130] ハッシュ鎖の探索では、距離を小さくするため、直近の文字列から探していきます。
ハッシュ鎖はどんどん[[連結]]していき、削除はしませんが、
古すぎるものは一致しても採用しません。 [SRC[>>116]]
[131] 圧縮器は、
一致したものの選択を遅延させても構いません (lazy matching)。
ある位置で一致しても、更に先でより長い一致があるなら、そちらを使うことにできます。
[SRC[>>116]]
* 復号 (展開)
[68] [VAR[入力ストリーム]]の[[復号]]は、次のようにします。 [SRC[>>26]]
ただし、[VAR[入力ストリーム]]から読むとは、現在位置から指定された長さのビット列を返し、
現在位置をその次のビットまで進めることをいいます。
[FIG(steps)[
= [74] [VAR[出力]]を、空バイト列に設定します。
= [90] 繰り返し、
== [69] [VAR[BFINAL]] を、[VAR[入力ストリーム]]から1ビット読んだ結果に設定します。
== [70] [VAR[BTYPE]] を、[VAR[入力ストリーム]]から2ビット読んだ結果に設定します。
== [92] [VAR[BTYPE]] が [N[11[SUB[2]]][0b11]] なら、
===
@@
== [71] [VAR[BTYPE]] が [N[00[SUB[2]]][0b00]] なら、
=== [72] [VAR[入力ストリーム]]の現在の[[バイト]]の残りの[[ビット]]をすべて読みます。
=== [73] [VAR[LEN]] と [VAR[NLEN]] を得ます。
=== [75] [VAR[入力ストリーム]]から [VAR[LEN]] [[バイト]]読んだ結果を、
[VAR[出力]]の末尾に追加します。
== [76] それ以外なら、
=== [77] [VAR[BTYPE]] が [N[10[SUB[2]]][0b10]] の場合、
==== [78] [VAR[符号]]を、符号木の表現を読んだ結果に設定します。
=== [125] それ以外の場合、
==== [126] [VAR[符号]]を、[[固定ハフマン符号]]に設定します。
=== [79] 繰り返し、
==== [80] [VAR[値]]を、[VAR[入力ストリーム]]から[[リテラル]]と長さの値を復号した結果に設定します。
==== [81] [VAR[値]] < [N[256]] なら、
===== [82] [VAR[出力]]の末尾に[VAR[値]]を追加します。
==== [83] それ以外なら、
===== [84] [VAR[値]] = [N[256]] (end of block) なら、
====== [85] 繰り返し (>>79) を終えます。
===== [86] それ以外なら [ [N[257]], [N[285]] ]、
====== [87] [VAR[入力ストリーム]]から距離を復号します。
====== [93] [VAR[位置]]を、[VAR[出力]]の長さ - [VAR[距離]]に設定します。
======
@@ [94] [VAR[位置]]が[[負]]の時、...
====== [95] 繰り返し、
======= [98] [VAR[出力]] [ [VAR[位置]] ] を、[VAR[出力]]の末尾に追加します。
======= [99] [VAR[位置]]を [N[1]] [[インクリメント]]します。
======= [88] [VAR[距離]]を [N[1]] [[デクリメント]]します。
======= [96] [VAR[距離]]が [N[0]] なら、
======== [97] 繰り返し (>>95) を終えます。
== [89] [VAR[BFINAL]] が設定されていれば、繰り返し (>>90) を終えます。
= [91] [VAR[出力]]を返します。
]FIG]
* 文脈
[1] [[DEFLATE]] は次の場面で用いられています。
[FIG(short list)[ [154] [[DEFLATE]] の[[応用]]
- [[zlib]]
- [[gzip]]
- [[ZIP]]
- [[LHA]]
- [[[CODE[zip]] (JWE)]] の値 [DFN[[CODE[DEF]]]] [SRC[>>160]]
]FIG]
[153] [[zlib]] と [[gzip]] は、 [[DEFLATE]] に簡単に[[ラップ]]した[[データ形式]]です。
[[zlib]] は[[メモリー]]上や通信での利用を想定した短いヘッダーと高速な整合性検査を採用しており、
[[gzip]] は[[ファイル]]としての利用を想定した[[メタデータ]]を格納できるようになっています
[SRC[>>155]]。
[REFS[
- [155] [CITE[Frequently Asked Questions about [[zlib]]]] ([TIME[2005-02-21 07:10:26 +09:00]]) <http://www.gzip.org/zlib/zlib_faq.html#faq19>
- [160] [CITE@en[[[RFC 7518]] - JSON Web Algorithms (JWA)]], [TIME[2019-11-27 04:11:14 +09:00]] <https://tools.ietf.org/html/rfc7518#section-7.3>
]REFS]
* 関連
[3] [[HTTP]] の[[内容符号化]] [CODE(HTTP)@en[[[deflate]]]]
については、 [[zlib]] を参照。
* 歴史
[9] [[DEFLATE]] は [DFN[[[RFC 1591]]]] によって定義されています。
[10] [[RFC 1591]] は第1.3版となっていますが、第1.1版から技術的内容は変わっていません [SRC[>>7]]。
;; [11] 第1.0版には言及がなく、存在したのか不明です。
[105] 当時としては一般的なスタイルの[[仕様書]]ですが、現代的には読みづらく厳密さが足りないといえます。
細部の規定が不十分だったり、似て非なる用語が (おそらく意図せず) 混在していたり、
同じことを異なる表現で解説しているだけなのか、別個の規定なのかはっきりしない似た記述が複数存在したり。
[2] [CITE@en[RFC 6713 - The 'application/zlib' and 'application/gzip' Media Types]]
([TIME[2015-09-27 13:20:11 +09:00]] 版)
<https://tools.ietf.org/html/rfc6713>
[FIG(quote)[
[FIGCAPTION[
[4] [CITE[zlib 入門]]
([TIME[2007-02-14 08:49:05 +09:00]] 版)
<https://oku.edu.mie-u.ac.jp/~okumura/compression/zlib.html>
]FIGCAPTION]
> zlib の圧縮アルゴリズムは PKZIP 2.x の deflate アルゴリズムで, もともとは私と吉崎栄泰さんが LHA のために開発したものをハッシュで高速化したものです(zlib のソースコード中に,ほんのちょっとですが私の名前が入っています)。 その後,LHA もハッシュを使うようになりましたので,LHA と gzip/zlib/Zip の実質的な相違はなくなりました。
]FIG]
[13] [CITE@en-US[Efficient XML Interchange (EXI) Format 1.0]]
( ([TIME[2011-03-10 23:00:15 +09:00]] 版))
<http://www.w3.org/TR/2011/REC-exi-20110310/#CompressedStreams>
[112] [CITE@en[RFC 8054 - Network News Transfer Protocol (NNTP) Extension for Compression]]
([TIME[2017-01-28 00:54:34 +09:00]])
<https://tools.ietf.org/html/rfc8054>
[156] [CITE[An Explanation of the DEFLATE Algorithm]]
([TIME[2002-04-14 04:20:49 +09:00]])
<http://www.gzip.org/deflate.html>