libjpegによるJPEGデータの展開

2004.1.17 NBUG例会

はじめに

libjpegによるJPEG圧縮の画像データをRGB無圧縮データに展開する方法の概要について述べる。なお、実際のコード詳細については、利用しているプログラムを参照されたい。


JPEG画像とは

一般にJPEG形式と呼ばれる圧縮方法は離散コサイン変換(DCT)を基本とした非可逆圧縮である。ロスレスJPEGもあるがここでは考えない。

離散コサイン変換とは、元のデータ列を関数とみなし、それを複数のcos波の合成波と考えて個々の周波数成分に変換することを示す。 この周波数成分の個々のパラメータを記録しておき、後程再度合成することによって、元の波形に近い波形を求めることができる。

元のデータ列そのものは記録しないので、圧縮→展開後は元のデータに「なんとなく特徴が似ている」ということになる。これが「自然画像に向いている」という理由となる。

JPEGではこのDCT変換だけでなく、ハフマン符号化圧縮等も利用している。


jpegライブラリ

JPEGのデータ形式は公開されているが、全て最初から自力で作るのは大変。そこでIJG注1 libjpegを使う。

NetBSDやFreeBSDのpkgsrc/ports注2にも当然あり、画像を扱う非常にたくさん(ほとんどの?)プログラムが利用している。

特徴

難点(あくまでも個人的に)

JPEG形式データの展開方法

ファイルから読み込むだけなら簡単。libjpeg.docにある通り。

  1. jpeg_create_decompress()
  2. ファイルオープン
  3. jpeg_stdio_src()
  4. jpeg_read_header()
  5. 展開パラメータ設定
  6. jpeg_start_decompress()
  7. while(データサイズ分) {
    jpeg_read_scanlines()
    1ライン分のRGBデータ読み込み
    }
  8. jpeg_finish_decompress()
  9. jpeg_destroy_decompress()

メモリ上のJPEG形式データ列を扱う

標準のファイルから読み出す手段は汎用性に欠ける。

そこでjpeg_stdio_src()相当のものを作る。これはj_decompress_struct という構造体に必要な関数を登録してやればよい。

仕様

作成関数

エラーハンドラ

標準のエラーハンドラが用意されており、そのまま使用すれば展開中にデータ不正等を検出した場合に終了(exit)する。

しかしデータの連続展開時等にはexitして欲しくなく、呼び出し元に戻りたいこともある。そのために独自のハンドラを追加することも可能である。

具体例

cpia2viewのjpeg_decode.cを見よ

これも読みにくくてスイマセン。


注1 Independent JPEG Group
注2 graphics/jpeg
注3 コンパイルフラグで変わる。とはいえ、PPMやBMPのいわゆるベタフォーマット

参考文献


$Id: using_jpeg.html,v 1.7 2004/01/20 15:05:54 oshima Exp $