あらためて英和辞典を引いて見てオドロいた。
zigzag ジグザグ[Z字, 稲妻]形(のもの)
walk in zigzag ジグザグに歩く
知らなかった。ジグザグって外来語なんだ…
(擬態語のたぐいかと思っていた)
ソレはさておき、Zigzag Scanなのである。
さて、RGB⇒YCbCr変換とDCT変換を経て、
配列YBR[x][y][k]にはk=0~2をYCbCr成分とし
x,y=0~7で各種周波数成分に対応する強度が
8x8のマトリックスで格納されている。
でもって、このマトリックスは左上のYBR[0][0][k]がDC成分で、
右下のYBR[7][7][k]へ向けて順次高周波成分へと並んでいるワケだが
ハフマン・ランレングスにデータを変換して行く順序はx,yに従う順ではなく
下図の赤破線の矢印で示した順番で行う。
この斜めに往復する順で逐次データアクセスすることを
ジグザグ・スキャンと称している。
とは言っても、アクセスの都度x,yの値を算出するのはメンドいので
ここで全てを並べ替えてZig[n][k]配列(k=0~2:YCbCr)に
n=0~63として一直線に並べ直してしまおう。
つまりは、こんなカンジに・・・
一応付け加えると、何故この並べ替えが「今」なのかなのだが・・・
実際の処理手順としてはハフマン・ランレングスにデータを変換する前に
指定Q値でスケーリングされた係数値による「量子化」処理を行うのだが、
この係数値はすでにJFIFヘッダを準備する段階でJPHead[ ]配列内に
作成済みになっている。
(元々Q=50での係数値が記述されているものをスケーリング変換したのだが)
このヘッダ上に記述されている量子化係数値は先のジグザグに沿って
並べ替えた順序になっている。
本dllでは、このJPHead[ ]配列内に用意した量子化係数列を使用して
量子化処理を行うので、ジグザグ並べ替えのタイミングは「今」なのである。
て、コトで以下をSub Functionsセクションに記述する。
/****
ZigZag Scan
****/
void ZigZag
(long YBR[][8][3], long Zig[][3]){
int x, y, k;
for (k = 0; k < 3; k++){ // Y,Cb,Cr
for (y = 0; y < 7; y += 2){
for (x = 0; y >= x; x++){
Zig[y*(y + 1) / 2 + x][k] = YBR[x][y - x][k];
Zig[63 - y*(y + 1) / 2 - x][k] = YBR[7 - x][7 - y + x][k];
}
}
for (x = 1; x < 8; x += 2){
for (y = 0; x >= y; y++){
Zig[x*(x + 1) / 2 + y][k] = YBR[x - y][y][k];
Zig[63 - x*(x + 1) / 2 - y][k] = YBR[7 - x + y][7 - y][k];
}
}
}
}
forループのぐるぐる回しで、
シンプルなようにも、ちからワザなようにも見える。
キモチとしてはもう少しキレイなものにしたいが
うまい手法を思いつかない。
次は量子化処理だ!
- つづく -
最新の画像[もっと見る]
- 勝手に何すんねん!? 5年前
- 勝手に何すんねん!? 5年前
- Jpeg保存dllのバグ修正 <長いものは、やはり長い> 6年前
- Jpeg保存dllのバグ修正 <長いものは、やはり長い> 6年前
- Jpeg保存dllのバグ修正 <長いものは、やはり長い> 6年前
- Jpeg保存dllのバグ修正 <長いものは、やはり長い> 6年前
- コンパイル&ビルド 6年前
- コンパイル&ビルド 6年前
- Huffman変換&圧縮処理のつづき 6年前
- ハフマン変換をLUTにする の続き 6年前