-
Notifications
You must be signed in to change notification settings - Fork 4
/
628.txt
204 lines (149 loc) · 10 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
* 仕様書
[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>
]REFS]
* アルゴリズム
[12] [RUBYB[入力データ]@en[input data]]は、[[ブロック]]の連なりです。 [SRC[>>25]]
[14] [RUBYB[圧縮データ集合]@en[compressed data set]]は、
[[ブロック]]の[[系列]]です。 [SRC[>>25]]
[20] [[圧縮されたデータ部分]]は、[[要素]]の[[系列]]です。各[[要素]]は、
[RUBYB[リテラルバイト群]@en[literal bytes]]か、
[RUBYB[重複列への指示子]@en[pointer to duplicated strings]]かのいずれかです。 [SRC[>>25]]
[21] [[指示子]]は、[RUBYB[長さ]@en[length]]と、[RUBYB[前方向の距離]@en[backward distance]]との組で表されます。 [SRC[>>25]]
[17] [[距離]]は、 32KB [[以下]]です。すなわち、[[指示子]]は、[[入力データ]]の
32KB 前までの[[ブロック]]の[RUBYB[列]@en[string]]を参照できます。 [SRC[>>25]]
[22] [[長さ]]は、 258 バイト[[以下]]です。 [SRC[>>25]]
[23] [[リテラル]]と[[長さ]]は、[[ハフマン符号木]]を使って[[ハフマン符号]]で表します。 [SRC[>>25]]
[24] [[距離]]は、別の[[ハフマン符号木]]を使って[[ハフマン符号]]で表します。 [SRC[>>25]]
[19] [[ハフマン木]]自体も、[[ハフマン符号化]]により圧縮します。 [SRC[>>25]]
** ビット列の表現
[27] [[DEFLATE]] の出力は[[バイト列]]です。
[[バイト]]内の[[ビット順]]は規定されておらず [SRC[>>26]]、
[[プラットフォーム]]や[[プロトコル]]に依存します。
[29] [[多バイト]]の値は、重みの小さな[[バイト]]から順に並べた[[バイト列]]
[SRC[>>26]] ([[小エンディアン]]) とします。
[28] [RUBYB[データ要素]@en[data element]]を[[バイト列]]にする際には、
[[バイト]]の重みの小さな[[ビット]] ([[LSB]]) から順に詰めていきます。 [SRC[>>26]]
[30] [[ハフマン符号]]''以外''のデータ要素は、
当該データ要素の LSB から順に詰めていきます。 [SRC[>>26]]
[31] [[ハフマン符号]]は、重みの大きな[[ビット]] ([[MSB]])
から順に詰めていきます。 [SRC[>>26]]
** ハフマン符号化
[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] この制限を設けることで、[[記号]]に対応する[[ビット長]]の[[リスト]]を示すだけで、
[[符号]]を記述できます [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]
** ブロック
[62] [[入力データ]]の[RUBYB[ブロック]@en[block]]の大きさは任意に決められますが、
[N[65535]] [[バイト]][[以下]]でなければなりません。[SRC[>>25]]
[63] [[圧縮データ集合]]の[RUBYB[ブロック]@en[block]]は、
入力データの各[[ブロック]]に対応します。 [SRC[>>25]]
[15] 各[[ブロック]]は、 [[LZ77]] [[アルゴリズム]]と[[ハフマン符号化]]の組み合わせにより、
[[圧縮]]します。 [SRC[>>25]]
[18] [[ブロック]]は、[[圧縮]]されたデータ部分の表現を説明する[[ハフマン符号木]]と、
[RUBYB[圧縮されたデータ部分]@en[compressed data part]]との2つの部分の組です。 [SRC[>>25]]
[16] 各[[ブロック]]の[[ハフマン木]]は、互いに独立です。 [SRC[>>25]]
* 文脈
[1] [[DEFLATE]] は次の場面で用いられています。
[FIG(short list)[
- [[zlib]]
- [[gzip]]
- [[ZIP]]
- [[LHA]]
]FIG]
* 適合性
[8] [[圧縮器]]は、[[仕様]]にすべて従うデータ集合を生成しなければなりません [SRC[>>7]]。
[6] [RUBYB[[[展開器]]]@en[decompressor]]は、
特に定める場合を除き、
[[仕様]]に[[適合]]する任意のデータ集合を[[受理]]し[RUBYB[[[展開]]]@en[decompress]]できなければなりません。 [SRC[>>7]]
* 関連
[3] [[HTTP]] の[[内容符号化]] [CODE(HTTP)@en[[[deflate]]]]
については、 [[zlib]] を参照。
* 歴史
[9] [[DEFLATE]] は [DFN[[[RFC 1591]]]] によって定義されています。
[10] [[RFC 1591]] は第1.3版となっていますが、第1.1版から技術的内容は変わっていません [SRC[>>7]]。
;; [11] 第1.0版には言及がなく、存在したのか不明です。
[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>