All-About調査室 Annex

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

Huffman変換&圧縮処理のつづき

2018-04-14 10:14:28 | 4:4:4 Jpeg保存dll作成

前回ハフマン変換のざっくりフローを述べたが
ややこしくてコトバだけではイメージがイマイチだ。
そこで、具体例のフローを図示してアタマを整理しよう。
(ややこしい処理ではコレをやらずにコーディングすると
大抵バグるのがワタシの常であるっ!)

で、例として8x8 pixの変換ブロックごとの段で数えて、
上から6段目の先頭ブロックのデータが15,12,0,0,9,…だったとする。
これに対応する変換コードをルックアップテーブル(LUT)から抜き出すと
以下のようになる。
(LUTはココココで作った)



さて、コレを使ってデータ保存用のバイト配列(unsigned char HD[]とする)に
32bitバッファを介してテータを詰め込んで行くのだが、
「上から6段目の先頭ブロック」なので、
まずリスタートマーカをHD[]に書き込む。
(このdllでは1段ごとにリスタートマーカを入れる仕様としたので)

リスタートマーカは16進表記でFF Dx (xは0~7)で、
DRIセグメントで定めたリスタートインターバルの処理ブロック数ごとに
その先頭に付記するが、一番最初のデータの前にはマーカを付けない。
またマーカ挿入位置が進むにつれ、FF Dx のxを0,1,2,…と値を増やして行くが、
FF D7の次は再度FF D0になり、再びxを0,1,2,…と増やして行く。

よって、上から6段目に付けるリスタートマーカは「FF D4」となる。
コレをまずバイト配列にHD[0]=0xFF、HD[1]=0xD4でセットし、
配列の2要素にデータが埋まったので、データ数カウンタを「2」とする。

次に最初のデータの「15」の変換を行う。
最初のデータは輝度YのDC成分の値であるので、
まず、L_Db[15+2047]によりデータのビット長「4」をLUTから得る。
(+2047するのはデータ範囲-2047~+2047をインデックス0~4094の配列にしているから)

このデータビット長「4」を用いてL_DCc[4]でハフマンコード「0xA000」を、
L_DCb[4]でハフマンコードの有効ビット長「3」を得る。

ハフマンコード「0xA000」をunsigned Longにキャストした後、
最初のデータなので16bit左シフトして「0xA0000000」として
32bitバッファにセットする。
32bitバッファ内の有効ビット長は先のハフマンコードの有効ビット長と同じなので、
バッファ有効長カウンタに「3」をセットする。

次にハフマンコードに続くデータ変換コードをL_Dc[15+2047]で「0xF000」と得る。

(+2047するのはL_Db[ ]配列と同じ理由)
ハフマンコードの時と同様にunsigned Longにキャストし、
16bit左シフトすれば「0xF0000000」なのだが、
32bitバッファには先のハフマンコードが有効長3bitで入っているので
有効部分が重ならないように3bit右シフトして「0x1E000000」にする。
コレと32bitバッファの内容とをbit OR演算して、結果を32bitバッファに入れる。
(32bitバッファは「0xBE000000」になる)



バッファ有効長カウンタはL_Db[15+2047]で得たビット長「4」が加わるので
先にセットされていた「3」と合計して「7」に改める。

次のデータ「12」の処理も同様だが、
AC成分なのでハフマンコードと有効長の参照LUTがL_ACcとL_ACbになる。
まずL_Db[12+2047]でデータビット長「4」であり、
このデータ直前のAC成分にゼロ値は無いのでL_ACc[0][4]とL_ACb[0][4]から
ハフマンコード「0xB000」、有効bit長「4」を得る。
んで、このハフマンコードを先と同様に処理すると
32bitバッファの中身は「0xBF600000」で有効長「11」になる。

32bitバッファの有効長が8以上になったので上位8bitをバイト配列に移す。
バイト配列のデータ数カウンタが2になっているので、HD[2]=0xBFとして、
データ数カウンタに1を加えて「3」に直す。
32bitバッファの方は8bit左シフトさせて「0x60000000」として、
有効長のカウンタは8減じて「3」に直す。

つづくデータ変換コードはL_Dc[12+2047]で「0xC000」でビット長「4」だったので、
先と同様に32bitバッファに詰め込むと「0x74000000」有効長「7」になる。

3・4番目のデータは共に「0」だが、これらはAC成分なので
ゼロカウンタだけをカウントアップさせて「2」とする。

5番目のデータは「9」でやはりAC成分だ。
まずL_Db[9+2047]でデータビット長「4」を得る。
2番目の時と異なり、直前のAC成分ゼロ値は「2」とカウントされているので
L_ACc[2][4]とL_ACb[2][4]からハフマンコード「0xFF40」、有効bit長「12」
を得る。

これを32bitバッファに詰め込むと「0x79FE8000」有効長「19」になる。
32bitバッファの有効長が8未満になるまでバイト配列にデータを移すので
HD[3]=0x79、HD[4]=0xFEとなって、バイト配列のデータ数カウンタは「5」になる。
32bitバッファは上位16bitが移ったので「0x80000000」で有効長「3」になる。

つづくデータ変換コードをコード「0x9000」、ビット長「4」で処理すると、
32bitバッファは「0x92000000」で有効長「7」になる。

このプロセスの様子を図にすると…



となる。

大まかなフローを確認したところで次回はコレをコーディングしよう。

- つづく -




最新の画像もっと見る

コメントを投稿

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