🦀

Rustでzopfliコマンドを作った話

2024/08/03に公開

zopfliコマンドのRust実装のrzopfliを開発しました。

https://github.com/sorairolake/rzopfli

Zopfliとは

ZopfliはGoogleが開発したDEFLATE形式、gzip形式、zlib形式と互換性のある可逆データ圧縮アルゴリズムです。

https://github.com/google/zopfli

Zopfliはデータを圧縮するときにより多くの時間を使うことで他のDEFLATEやzlibの実装よりも高い圧縮率を実現しています。
Zopfliが生成するDEFLATEストリームは他のDEFLATEやzlibの実装が出力するDEFLATEストリームと同じくらいの時間で展開できます。

リファレンス実装にはデータを生のDEFLATEストリーム、gzipファイル、zlibファイルに圧縮するzopfliコマンドと、Zopfliを使ってPNG画像を最適化するzopflipngコマンドが付属しています。

作った理由

  1. zopfliコマンドの機能が不足しているように感じたから。
  2. Rustで何かを作りたかったから。

インストール方法

ソースコードから

Cargoを利用してインストールすることができます。

cargo install rzopfli

ビルド済みバイナリから

リリースページでLinux、macOS、Windows向けのビルド済みバイナリを公開しているので、これをインストールすることもできます。

使い方

rzopfliのコマンドライン構文はgzip(1)zstd(1)を参考にして、そこにzopfliコマンドのいくつかのオプションを追加しています。

$ rzopfli -h
A lossless data compression tool using Zopfli

Usage: rzopfli [OPTIONS] [FILE]...

Arguments:
  [FILE]...  Files to compress

Options:
  -c, --stdout                       Write to standard output, keep original files
  -f, --force                        Force compression even if the output file already exists
  -k, --keep                         Keep input files
      --rm                           Remove input files after successful compression
  -i, --iteration <TIMES>            Perform compression for the specified number of iterations
                                     [default: 15]
      --format <FORMAT>              Output to the specified format [default: gzip] [possible
                                     values: gzip, zlib, deflate]
      --log-level <LEVEL>            The minimum log level to print [default: INFO] [possible
                                     values: OFF, ERROR, WARN, INFO, DEBUG, TRACE]
      --generate-completion <SHELL>  Generate shell completion [possible values: bash, elvish, fish,
                                     nushell, powershell, zsh]
  -h, --help                         Print help (see more with '--help')
  -V, --version                      Print version

デフォルトでは、zstdコマンドと同様に入力されたファイルを削除しないようになっています。
zstdコマンドと同様に--rmオプションを指定することで圧縮が成功した後に入力されたファイルを自動的に削除できます。

データを圧縮する

何もオプションを指定しないときは引数に指定されたファイルをgzipに圧縮します。

$ rzopfli foo.txt
12:38:15 [INFO] Saving to: foo.txt.gz
12:38:15 [INFO] Original Size: 1.04 KiB, Compressed: 614 B, Compression: 42.46% Removed

--formatオプションを指定すると出力形式をgzipファイル(デフォルト)、zlibファイル、zlibファイルに変更できます。

$ rzopfli --format zlib foo.txt
12:41:26 [INFO] Saving to: foo.txt.zlib
12:41:26 [INFO] Original Size: 1.04 KiB, Compressed: 602 B, Compression: 43.58% Removed

圧縮処理の反復回数を変更する

デフォルトでは、rzopflizopfliコマンドと同様に15回圧縮処理を反復します。
-iオプションを指定することでzopfliコマンドの--iオプションのように圧縮処理の反復回数を変更できます。

$ rzopfli -i 1000 foo.txt
12:49:37 [INFO] Saving to: foo.txt.gz
12:49:38 [INFO] Original Size: 1.04 KiB, Compressed: 612 B, Compression: 42.64% Removed

終わりに

rzopfliを紹介しました。
この記事を読んで興味を持った場合は、実際にrzopfliを試していただけると嬉しいです。

GitHubで編集を提案

Discussion