圧縮データ用の出力バッファーを割り当てる必要があるため、この質問があります。圧縮アルゴリズム (gzip、zip、snappy など) の出力が入力よりも確実に小さいサイズを知る必要がありますか?
5 に答える
非可逆圧縮アルゴリズムの場合、これが当てはまる可能性がありますが、保証はされていません。ロスレス圧縮アルゴリズムの場合、これは当てはまりません。ロスレス圧縮は常に、一部の入力の入力よりも大きな出力を生成します。理由については、このウィキペディアのページを参照してください。
zlib (gzip 用) を使用している場合は、次のインターフェイスが役立つことがあります: (からzlib.h
)
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
compress() or compress2() on sourceLen bytes. It would be used before
a compress() or compress2() call to allocate the destination buffer.
*/
bzip にも同様のインターフェースがあると思います。返される値は sourceLen よりもわずかに大きく、メモリ内で圧縮できるほど小さいデータが圧縮されている場合にのみ使用する必要があります。ただし、そのようなアプリケーションでは、非常に便利です。
ほとんどの場合、割り当てられたメモリのほとんどを使用しないことに注意してください。そのため、圧縮されたバージョンを一定期間メモリに保持する予定がある場合は、未使用のメモリを返すこともできます。
「ヘッダー」には常に固定サイズが関連付けられていますが、実際のデータ (このコメントの長さなど) については、通常は圧縮が役立ちます。
つまり、圧縮後のバッファを入力バッファと同じサイズに宣言するのは「安全」ではありません。もっと大きいかもしれません。
いいえそうではありません。
簡単な例: 均一に分散された反復しない値を持つデータは、損失なしでは圧縮できないため、元のデータと添付されたメタ データが得られます。
zlib (gzip および pkzip で使用されるインフレート/デフレート用) などの圧縮ライブラリは、入力および出力最大 M バイトから最大 N バイトをユーザー割り当てバッファーに処理するように設計されている可能性が高く、ライブラリが新しい入力を予期する場合は呼び出し元に通知します。データまたは新しい/クリアされた出力バッファ。これらのライブラリは、完全な入力と出力がメモリに存在することを期待しているのに、ブロックで動作することはめったにありません。
また、多くの一般的なアルゴリズムの「検索ウィンドウ」は比較的小さいです。これにより、必要なメモリ量も制限されます。tar.bz2 で使用される BWT などの反例が存在します。
また、他の人が指摘しているように、可逆圧縮アルゴリズムの出力は入力よりも大きくなる可能性があります。その場合、適切に設計された圧縮ライブラリのほとんどは、圧縮されていないブロックをサイズ情報とともにコンテナーにラップするだけのフォールバック メカニズムを自動的に実装します。
要約すると、多くの圧縮ライブラリは、数キロバイトから数メガバイトのバッファを必要とし、それを使用して任意の長さの入力を処理します。(このような制約は MPEG に含まれています -- 予想されるフレーム サイズ (たとえば、mp3 では 128 kbps) に加えて、必要な最大バッファ サイズが指定されています)