それではzlibによるDeflateアルゴリズムで圧縮されたzipアーカイブファイルのプログラミングを行ってみましょう。以前紹介した無圧縮zipにおけるヘッダとの主な違いは以下の2つです。

 zlibライブラリによる圧縮ルーチンも前回紹介した圧縮ルーチンと異なる点があります。ひとつめは、圧縮が終了したら「deflateEnd」を指示してメモリを解放していましたが、対象のファイルを扱うたびに「deflateEnd」「deflateInit」を繰り返すとやや非効率なので、z_streamデータの再初期化は行うものの、メモリの解放は行わない「deflateReset」関数をプログラムに挿入します。

 特に何もしない状態でdeflateを実行すると、deflateに関する情報がヘッダとして自動的に出力バッファに追加されます。しかし、zipファイルはヘッダ内で圧縮に関するデータが含まれているため、zlibのヘッダは不要などころか、アーカイバはこのzlib自体が出力したヘッダを不正なデータと判断してしまうため、deflateInitの拡張関数である「deflateInit2」でヘッダ出力をしないオプションを指定しなくてはいけません。

deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);

 引数の1番目にはz_stream構造体を、2番目には圧縮度(0~9)、3番目には圧縮方法(Z_DEFLATED固定)、4番目には圧縮のために確保するメモリ領域(1で最小、9で最大。8が標準。確保量が少ないと計算に時間がかかり、圧縮効率が低下する)、5番目には圧縮アルゴリズムの調整(Z_HUFFMAN_ONLYは単語などおなじバイナリ集合が多いデータ向き、Z_RLEはベタ画像のような連続するバイナリが続くデータ向き、Z_DEFAULT_STRATEGYは両者の中間)を指定します。

 最も重要なのが3番目の履歴バッファのサイズ(8~15の範囲内。数値が大きいとメモリ消費量は増えるが、圧縮効率はよくなる)で、この値をマイナスにすると、ヘッダの付加されない圧縮データが生成されるようになります。

 また、zlibライブラリにはcrc32を算出するための関数が用意されており、既存のcrc32関数と入れ替えることもできるのですが、次回紹介する暗号化におけるCRC32計算においては、zlibの関数はやや扱いづらいので、独自のCRC32関数を引き続き利用します。