ebclient/lib/ebu/doc/ebzip-10.html
Jacques De SAGAN 03de9e18bb first import
2024-04-07 11:52:06 +08:00

336 lines
9.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<link rel="stylesheet" type="text/css" href="ebutils.css">
<link rev="made" href="mailto:m-kasahr@sra.co.jp">
<title>ebzip コマンド</title>
</head>
<body>
<p>
[<a href="ebzip-09.html">前へ</a>] [<a href="ebzip.html#toc">目次</a>]
</p>
<hr>
<h2><a name="compressed-file-format">圧縮ファイルの形式</a></h2>
<p>
この章では、<code>ebzip</code> が扱っている圧縮ファイル形式の詳細について説
明します。
</p>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h3><a name="format-overview">圧縮ファイル形式の概要</a></h3>
<p>
圧縮ファイル形式は次のような特徴を持っています。
</p>
<ul>
<li>CPU の種類、オペレーティングシステム、ファイルシステムに依存しません。
<li>非損失圧縮です。<br>
圧縮ファイルを伸長することによって、元のファイルを復元できます。
<li>6 つの圧縮レベルがあります。<br>
伸長の速さか圧縮率の良さの、いずれかを選ぶことができます。
</ul>
<p>
圧縮されたファイルは、ヘッダ部、インデックス部、およびデータ部から構成
され、この順でファイルに配置されます。
</p>
<blockquote>
<pre>
+--------+-------------+-----------------------------+
| ヘッダ |インデックス | データ |
+--------+-------------+-----------------------------+
EOF
</pre>
</blockquote>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h3><a name="format-data-part">データ部</a></h3>
<p>
元のファイルは、次の行程で圧縮されます。
</p>
<p>
まず、<code>ebzip</code> は元のファイルを分割します。
個々の <dfn>スライス</dfn> (<dfn>slice</dfn>) は、末尾のものを除けば、
同じ大きさになっています。
</p>
<blockquote>
<pre>
+---------------+---------------+-- --+----------+
| スライス 1 | スライス 2 | ... |スライス N|
+---------------+---------------+-- --+----------+
EOF
</pre>
</blockquote>
<p>
スライス・サイズは、圧縮レベルから決まります
(圧縮レベルについては <a href="ebzip-04.html#compression-level">「圧縮レベル」</a>
参照のこと)。
</p>
<table summary="圧縮レベルとスライスの大きさの対応表">
<tr><td>圧縮レベル <td> スライスの大きさ</tr>
<tr><td>0 <td> 2048 バイト</tr>
<tr><td>1 <td> 4096 バイト</tr>
<tr><td>2 <td> 8192 バイト</tr>
<tr><td>3 <td> 16384 バイト</tr>
<tr><td>4 <td> 32768 バイト</tr>
<tr><td>5 <td> 65536 バイト</tr>
</table>
<p>
次に、末尾のスライスがスライス・サイズよりも短かった場合、
<code>ebzip</code> はスライス・サイズと同じになるまで伸ばし、伸ばした
部分に 0x00 を埋めます。
</p>
<blockquote>
<pre>
伸した部分
+---------------+---------------+-- --+---------+-----+
| スライス 1 | スライス 2 | ... | スライス N |
+---------------+---------------+-- --+---------+-----+
EOF
</pre>
</blockquote>
<p>
最後に、<code>ebzip</code> は個々のスライスを、RFC 1951 に記されている
DEFLATE 圧縮データ形式で圧縮します。
おのおののスライスは、他のスライスとは独立して圧縮されます。
圧縮されたスライスのビット数が 8 の倍数でなければ、1 7 ビットを圧
縮されたスライスの末尾に足し、8 の倍数になるようにします。
これにより、圧縮されたそれぞれのスライスはバイトの境界から開始されます。
足されたビットの内容は未定義ですが、このビットは決して使用されません。
</p>
<blockquote>
<pre>
+------------+----------+-- --+--------------+
| 圧縮された |圧縮された| ... | 圧縮された |
| スライス 1 |スライス 2| ... | スライス N |
+------------+----------+-- --+--------------+
</pre>
</blockquote>
<p>
これが圧縮ファイル形式における <dfn>データ部</dfn> になり、圧縮された
スライスから構成されます。
</p>
<p>
末尾のスライスの伸ばした部分は、末尾のスライスの一部として圧縮され
ます。
<code>ebunzip</code> が末尾のスライスを復元するときは、スライスを伸長して
から伸ばした部分を取り除くという作業を行います。
</p>
<p>
圧縮したスライスの大きさが、スライス・サイズよりも大きいか等しいときは、
<code>ebzip</code> はそのスライスの圧縮データを廃棄します。
この場合、<code>ebzip</code> は元のデータをそのスライスの圧縮データとして
代わりに記録します。
</p>
<p>
元のファイルが空だったときは、圧縮ファイルのデータ部はありません。
</p>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h3><a name="format-index-part">インデックス部</a></h3>
<p>
圧縮時に、<code>ebzip</code> は圧縮した個々のスライスの
<dfn>インデックス</dfn> (<dfn>index</dfn>) を記録します。
個々のインデックスは、圧縮ファイルの先頭から圧縮されたスライスの先頭
までの距離を表します。
距離の単位はバイトです。
</p>
<blockquote>
<pre>
+---------+---------+-- --+---------+---------+
|インデッ |インデッ | ........... |インデッ |インデッ |
|クス 1 |クス 2 | ........... |クス N |クス END |
+---------+---------+-- --+---------+---------+
| | | |
+---+ +----+ +------+ +-----------+
V V V V
+------------------+------------------+-- --+--------------+
| 圧縮された | 圧縮された | ... | 圧縮された |
| スライス 1 | スライス 2 | ... | スライス N |
+------------------+------------------+-- --+--------------+
</pre>
</blockquote>
<p>
個々のインデックスは 2 5 バイトの大きさを持ちます。
インデックスの大きさは、元のファイルの大きさで決まります。
</p>
<table summary="元のファイルの大きさとインデックスの大きさの対応表">
<tr><td>元のファイルの大きさ <td> インデックスの大きさ</tr>
<tr><td> 0 65535 バイト <td> 2 バイト</tr>
<tr><td> 65535 16777215 バイト <td> 3 バイト</tr>
<tr><td> 16777216 4294967295 バイト <td> 4 バイト</tr>
<tr><td>4294967296 1099511627775 バイト <td> 5 バイト</tr>
</table>
<p>
インデックス内での、複数バイトからなる数値はすべて、値の大きい方の部分
を表すバイト (most significant byte) が先に来た形で記録されます。
たとえば、0x1234 は次のように記録されます。
最初のバイトは 0x12 となり、次のバイトは 0x34 になります。
</p>
<blockquote>
<pre>
+---------+---------+
|0001 0010|0011 0100|
+---------+---------+
(0x12) (0x34)
</pre>
</blockquote>
<p>
インデックス部は、圧縮されたスライス 1 のインデックスで始まり、その後ろ
に圧縮されたスライス 2 のインデックスが続きます。
圧縮されたスライス N のインデックスの後ろには、「終端」へのインデックス
が置かれます。
このインデックスは、圧縮されたスライス N の末尾の次のバイトへの
インデックスになります。
また、圧縮されたファイルのサイズを示すことにもなります。
</p>
<blockquote>
<pre>
+---------+---------+-- --+---------+---------+
|インデッ |インデッ | ........... |インデッ |インデッ |
|クス 1 |クス 2 | ........... |クス N |クス END |
+---------+---------+-- --+---------+---------+
</pre>
</blockquote>
<p>
圧縮されたスライスの大きさがスライスサイズに等しいときは、そのスライス
のデータは実際には圧縮されていないことを示します。
</p>
<p>
元のファイルが空だったときは、インデックス部はインデックスを一つだけ
持ちます。
このインデックスは圧縮されたファイルの大きさを表します。
</p>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h3><a name="format-header-part">ヘッダ部</a></h3>
<p>
ヘッダ部は 22 バイトからなります。
次のフィールドから構成されます。
</p>
<blockquote>
<pre>
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| マジック ID |*1| *2 |ファイルの大きさ | Adler-32 | 修正時刻 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
*1: zip モードと圧縮レベル
*2: 予約領域
</pre>
</blockquote>
<dl>
<dt><code>マジック ID (5 バイト)</code></dt>
<dd>
0x45, 0x42, 0x5a, 0x69, 0x70 (ASCII 文字列で表すと <samp>EBZip</samp>)
という固定した値を持ちます。
<dt><code>zip モード (MSB 側の 4 ビット)</code></dt>
<dd>
圧縮モードを表します。
元の (非圧縮時の) ファイルの大きさが 4294967295 バイト (= 4Gバイト)
以内のときは 1 (2 進数で 0001)、それより大きいときは 2 (2 進数で 0002)
をセットします。
<p>
ファイルの大きさで値が変わるのは、歴史的な事情によります。
以前の EB Library は圧縮モード 1 しか既定しておらず、また 4GB バイト
を超えるファイルを扱えませんでした。
4G バイトを超えるファイルを扱えるように EB Library を改良した際に、
「4G バイトを超えたら、圧縮モードは 2 にセットする」というルールを
新たに設けました。
これにより、以前の EB Library で 4GB バイトを超えたファイルを扱おう
とすると、非対応の圧縮モードとみなされ、エラーが発生するようになって
います。
</p>
<dt><code>圧縮レベル (LSB 側の 4 ビット)</code></dt>
<dd>
圧縮レベルを表します。
<dt><code>予約領域 (2 バイト)</code></dt>
<dd>
予約されていますが、使われていません。
0x0000 で埋められます。
<dt><code>ファイルの大きさ (6 バイト)</code></dt>
<dd>
元の (非圧縮時の) ファイルの大きさを記録しています。
<dt><code>Adler-32 (4 バイト)</code></dt>
<dd>
RFC 1950 に記されている Adler-32 というアルゴリズムを用いて計算した、
非圧縮データのチェックサムの値です。
<dt><code>修正時刻 (4 バイト)</code></dt>
<dd>
元のファイルの最終修正時刻です。
グリニッジ標準時の 1970 年 1 月 1 日 0 時 0 分 0 秒からの経過秒数で
表します。
</dl>
<p>
<code>zip モード</code><code>圧縮レベル</code> は、両方ともヘッダの
5 バイト目に入ります。
<code>zip モード</code> は、値の最も大きい部分を表すビット
(most significant bit) を含み、<code>圧縮レベル</code> は最も小さい部分を
表すビット (least significant bit) を含んでいます。
<code>zip モード</code> が 1 で、<code>圧縮レベル</code> が 2 なら、
ヘッダの 5 バイト目は 0x12 になります。
</p>
<blockquote>
<pre>
MSB LSB
+---+---+---+---+---+---+---+---+
| 0 0 0 1 0 0 1 0 | = 0x12
+---+---+---+---+---+---+---+---+
(zip モード) | (圧縮レベル)
</pre>
</blockquote>
<p>
ヘッダ内での、複数バイトからなる数値はすべて、値の大きい方の部分
を表すバイト (most significant byte) が先に来た形で記録されます。
</p>
<hr>
<p>
[<a href="ebzip-09.html">前へ</a>] [<a href="ebzip.html#toc">目次</a>]
</p>
</body>
</html>