Tech と Culture

テクノロジーとカルチャー

IJG YccRGB conversion

jdcolor.cのソースコードのコメントにもあるように、Ycc->RGB color conversionは以下のような単純な演算で変換できる。

* R = Y + 1.40200 * Cr
* G = Y - 0.34414 * Cb - 0.71414 * Cr
* B = Y + 1.77200 * Cb

ソースコードの方を見てみると、
> /* Range-limiting is essential due to noise introduced by DCT losses. */
> outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
> outptr[RGB_GREEN] = range_limit[y +
>    *1];
>              outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
>

のように掛け算が配列になっており、全体もrange_limitという配列になっている。
range_limitはただ単に0以下なら0にして、256以上なら256に固定するというものを最初から配列に入れておき、その指数としてカラー変換演算をとっている。
これは何をやっているかというと、各ピクセル毎にこの演算があるため、高速化することを狙っていると思われる。特にIJGは基礎ライブラリーとして提供されているので、Integer Unitのみを使用して高速化することを狙っていると予想しました。
その他のカラー変換も同じようなものですが、123シフトさせてから演算させているものもあります。

ここら辺はソースコードを読んだら、速度が遅くなっても良いので倍精度でも良いので単純な式で書き換えたものをコンパイルして一枚の絵をデコードさせます。それで問題なく絵がXwindow上に表示されればOK.
理解が間違っていないことが確認できます。
今後、ハードウェア化を進めていきますが、RTLのシミュレーションでも同じように進めていくつもりです。
ハードウェア化するCの関数の入力ベクターをファイルに書き出し、RTLシミュレーションのテストベンチ入力パターンとして、RTLモジュールの出力するベクターをファイルに書き出し、別のプログラムで表示させて絵がでればOK!
出力に近い関数からハードウェア化していくので簡単です。日曜工作なので入力のJPEG画面サイズもいくつかに決めうちします。パッディングなどが必要ではないサイズで決めうちです。

IJGのライブラリがおそらく整数演算しか使っていないと想像しています。LINUXのカーネルも、もちろん整数演算しか使用していないと考えられます。何故、そこを気にしているかというと、私の使っているFPGASPARTAN-3のXC3S-1500なのですが、現在は95%ぐらい使用率があります。そこで使える領域を増やすために何かを省かないといけないのですが、今のところFPUを省いても性能に影響がないのではないかと想像しています。FPUはかなり大きいので領域確保に効果絶大です。

*1:int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], >                SCALEBITS