MozJPEG

今回はMozilla ResearchのMozJPEGについて書いていこうと思います。

以前、googleのguetzli JPEGエンコーダについて書いた際に、こちらを合わせてテストしてみた所、良い感じでしたので少し興味を持ち調べてみました。

MozJPEG はMozilla Researchとそのスタッフが中心となって開発が進められているJPEGライブラリの1つです。
libjpeg-turboのコードを元にしており(※1)、オリジナル版と比較してエンコード時のより良い品質と容量のトレードオフを目標としているようです。

API/ABIはlibjpegと互換性があり、”libjpeg”(又はlibjpeg-turbo)と置き換えて使用することができます。

まず最初に、MozJPEGにおける特徴を幾つか書いていこうと思います。
これらの特徴は全てエンコード(一部はトランスコード)時のものです。

1. ハフマン圧縮の最適化

MozJPEGはプログレッシブモード(※2)において、オリジナル版のlibjpegよりもより効率的なハフマン圧縮を行うことができます。残念ながらその効果はベースラインモード(※2)では見込めないのですが、プログレッシブモードへの変換は無劣化で行えるため、保存用に小さくしたい場合などには有用です。

2. 標準とは異なる量子化テーブル

MozJPEGは一般的な量子化テーブル(※3)とは異なるテーブルがデフォルトで使用されています。JPEGでは量子化テーブルはエンコーダ側で自由に設定することが可能ですが、多くのアプリケーションではAnnex Kと呼ばれるテーブルが使用されています。しかしながら、MozJPEGのデフォルト係数はImageMagickテーブルが使用されています。
また、MozJPEGでは以上に上げた2つのテーブル以外にも複数のテーブルがプリセットされており、エンコード時に選択することが可能です。

3. Trellis 量子化

Trellis 量子化と呼ばれる手法がエンコード処理に導入されています。
これは量子化処理時に行われる値の丸め処理を一定値で行うのではなく、最終的なデータ量と特定の評価基準とを照らし合わせて決定していく、というものです。
現在のところ、MozJPEGでは評価基準として4つのプリセットが用意されています。

4. サブサンプリング

これは色情報を事前にどのような比率にするか(間引くか)を決定します。
オリジナルの”libjpeg“や”libjpeg-turbo“では通常”YCbCr 4:2:0″が使用されています。一方で、MozJPEGではQuality値によってこの値は自動的に変更されます。
バージョン3.2においては、Quality80未満は”YCbCr 4:2:0″、Quality80~89は”YCbCr 4:2:2″、Quality90以上では”YCbCr 4:4:4″でエンコードされます。
もちろんエンコード時にこの初期値を別の値で上書きすることは可能です。


以上の4つが大元のライブラリ(以下 “IJG libjpeg“)と比較して、圧縮率に影響を与える主要な要素となります。
ハフマン圧縮最適化以外はエンコード時にのみ適用されるものです。

それでは実際に、ある写真をエンコードしてみて、”IJG libjpeg“と比較してどのようにデータ量が変化するかを見てみましょう。以下は手持ちのカメラで撮った写真のデータ(JPEGファイル)を再エンコードしたものです。

グラフA横軸がQuality値で1から100の値をとります。縦軸は出力されたファイルの容量(単位はバイト)です。

エンコード設定はどちらもBaselineを指定、ハフマン圧縮最適化は有効です。

この設定での比較では高いQuality値では”IJG libjpeg“よりもサイズが大きくなってしまっています。

実はこういった結果となった原因は、MozJPEGのデフォルト・サブサンプリングの設定によるものです。サブサンプリングの項目に書いたように、MozJPEGでは高Quality設定では”IJG libjpeg“とは異なるデフォルト設定値が使われます。

これを”IJG libjpeg“に合わせてYCbCr 4:2:0を指定した場合、以下のような結果になりました。

グラフB図では見にくいですが、Quality98を除いてMozJPEGのほうが出力サイズが小さくなっています(※4)。

この結果について1つ注意して欲しいことは、同じQuality値だからといって実際の出力品質が同じとは限らない、ということです。これは品質の評価では無く、あくまで指定Quality値に対する出力サイズの比較になります。

…さて、MozJPEGは他のアプリケーションから利用できるライブラリ、という形だけではなく、エンコーダ、デコーダ、トランスコーダなども配布されています。これらは”libjpeg”由来のコマンドライン(コンソール)プログラムですが、MozJPEG特有の拡張がされているものもあります。

次回はそんなコマンドラインから使用できるエンコーダの”cjpeg“やトランスコーダーである”jpegtran“を取り上げていく予定です。

 

※1 libjpeg-turboIJG(Independent JPEG Group)libjpegをSIMD命令等を使い高速化したものです。

※2 プログレッシブモードはベースラインモードとはエンコード後のデータの並び順が異なります。そのため、全体のデータを読み終えていない段階で画像の全体像を表示(デコード)することができます。
基本的にプログレッシブモードのJPEGのデコード処理は、ベースラインモードのそれよりも重い(遅い)です。

※3 量子化テーブルはエンコード・デコード時に使われる量子化係数テーブルです。この部分がJPEGの高い圧縮率と固有のアーティファクトを生み出す要因です。

※4 これは特定の画像についてのテスト結果であり、他の画像でも同じ結果、若しくは同じ傾向になるとは限りません。

コメントを残す