LoginSignup
2

More than 5 years have passed since last update.

7razf/7bgzf - RAZF/BGZF compressor based on 7-zip/zopfli

Last updated at Posted at 2015-10-06

前説

これまでcisoやdaxcrといった、PSP用のseekable compressorの再実装を行ってきた。次に着手しようと考えたのはRAZF/BGZFである。
RAZF/BGZFはバイオインフォマティクスのsamtoolsで使われる圧縮フォーマットであり、gzip拡張である。学術であることから、cisoやdaxcrよりも広く使われているだろうと想像できる。また、広く使われているgzipで展開できることも特徴である。

なお、これらの圧縮フォーマットは、実際には、PSP/バイオインフォマティクスにかぎらず、 general purposeである ことに留意されたい。

BGZF

BGZFの構造は容易である。各ブロックは独立したgzipであり、エクストラフィールドとして"\0BC\x02\0"+(ブロックサイズ-1、リトルエンディアン)を記録すればよい。この数値は65535以下でなければならない。ヘッダは18バイト、フッタは8バイトであるから、圧縮後のサイズが65510以下であれば良い。

RAZF

BGZFをランダムアクセスするには、ブロックの開始位置をgzipフィールドによらずに知る必要がある。RAZFは(cisoと同様)ファイルの一部分(今回はフッタ)を見ればブロックの開始位置を知ることができる。
RAZFはgzipのエクストラフィールドとして"RAZF\x01\x80\x00"を持つ。この0x8000はブロックサイズを示す。

オフセットの指定方法は少々トリッキーである。最初のブロック(-1ブロック)はヘッダ終了位置なので書かれておらず、次のブロック(0ブロック)以降は、大区切り( (1LLU << 32)/block_size )ごとに8バイト絶対オフセット、小区切りごとに大区切りからの4バイト相対オフセットを記録する(この部分、仕様書がなかったのでソースから読み取る必要があり辛かった)。
また、gzipで展開できるよう、deflate(Z_FINISH)ではなくdeflate(Z_FULL_FLUSH)を用いている特徴がある。7-zip/zopfliは仕様上Z_FULL_FLUSHを指定できないので、Z_FINISHから変換する処理が必要となる。変換する必要があるのは、deflateブロックの最終ブロックの最終フラグ解除、および再ブロックの継続である。
今回は、Z_FINISHなブロックを一旦展開しなおし、この2つのオフセットを取得することに成功した(7razf_testdecode.c)。

入手

余談

オプションパーサはpoptを使用。非コピーレフトで、かつgetoptぐらい強力。最近開発が止まっているようなので適当に直した。
(getopt使った結果ファイルごとにライセンスが分断されたソフト、いくつも見てるので)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2