All-About調査室 Annex

ふと湧いた疑問や巷を漂うウワサを全部アバウト~に調査・検証
<OCNから漂着 流浪の調査室>

Huffman変換&圧縮処理

2018-04-08 23:59:01 | 4:4:4 Jpeg保存dll作成

量子化処理後のデータをハフマン変換するための
ルックアップテーブルができたので、
コレを使って実際に変換を行う処理を作るのだが、
ここでざっくりとハフマン変換フローの方針を述べる。

ここまでにRGBデータをYCbCr変換して
離散コサイン変換(DCT)、Zigzagスキャン、量子化を行って
その結果がZig[64][3]配列に入っている。

このZig配列から1要素ずつデータをデータを取り出すごとに
先のルックアップテーブル(LUT)を参照して
ハフマンコードとデータ値に変換し、
同じくLUTから得られた有効bit数に基いて、
可変bit長データとしてギッシリ詰め込んで行く。

作成したLUTではハフマンコードもデータ値も有効bitを「左詰め」とし、
その右に無効bitを「ゼロ」で記述してあるので、
新たな変換データを詰め込む際には、
そこまでの有効bit分だけビット右シフトさせた上で
ビットOR演算すればデータ追加できる。

この詰め込み作業用に符号無し32bit変数をバッファとして使用し、
この変数の中で有効bit数が8bitを越えるたびに上位の(左の)
8bitを取り出してデータ保存用のバイト配列にコピーして行く。
モチロン、コピーしたら32bitバッファのデータを8bit左シフトさせ、
有効bit数のカウント値を8減するし、
データ保存用バイト配列では何バイトまでデータを確保したのかを
カウントアップしておく。

なお、本Jpeg保存dllでは8x8 pixの変換ブロックの水平1段分を
処理するごとにリスタートマーカを挿入する方針なので、
データ保存用のバイト配列はこのブロック水平1段分を確保しておき、
(DCTなど、ここまでの処理は8x8の変換ブロック単位に行ってきたが)
水平1段分のデータ詰め込みが終わるごとに
このバイト配列のファイル書き込みを実行することにする。
従って、水平1段分の処理が終わるまでは
(次のブロックのDCT処理を行っている間など)
データ保存用のバイト配列はモチロン、32bitバッファのデータも
その中の有効bit数の情報も保持している必要がある。

以前、AC成分のハフマン変換で述べたように
AC成分ではゼロ値は直接ハフマン変換せず、
ゼロ値の連続個数と直後のゼロ以外の値との組み合わせでコード化するので
AC成分の処理ではゼロ値の個数をカウントするカウンタが必要だ。

ついでにJpegの細かいキマリゴトなのだが、
変換後のバイトデータが(つまりデータ保存用バイト配列上で)
「FF」となった場合は、Jpegセグメント・マーカと区別するために
直後に「00」を挿入しなければならない。
また、エンドマーカ(FF D9)やリスタートマーカ(FF D0 ~ FF D7)は
必ずバイト境界から記述しなければならないが、
(つまりファイルをバイナリエディタで見て、必ず「FF D9」などと読める)
その直前のデータ終端は可変ビット長なので、
必ずしもバイト境界になるとは限らない。
この場合、データ終端とマーカ(つまりバイト境界)との間のスキマのbitは
「1」で埋める(スタッフィング・ビット)ことになっている。

次回は以上のナガレを具体例で示そう。
(必ずしもわかりやすくは無いんだけど)

- つづく -



最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。