All-About調査室 Annex

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

Jpeg保存dllのバグ修正

2018-05-11 22:31:40 | 4:4:4 Jpeg保存dll作成

あ~見つけてしまった!
つぶしきったと思っていたのだが、探して見るとあるもんだ。

ほぼ問題に遭遇する人はいないだろうし、
遭遇しても問題に気付くこともまず無いだろうが
気色悪いので直しておこう。

問題は量子化係数を指定Q値でスケーリングする部分にあった。

IJG推奨の量子化係数のスケーリング方法は
まず指定Q値をスケーリング係数Sに以下で変換する。
i)  Q<50のとき S = 5000/Q
ii) 上記以外のとき S = 200 - 2xQ

次に輝度と色差のQ=50での量子化係数テーブルを以下として



この各成分にスケーリング係数Sを掛けて100で割り、
小数部を四捨五入で整数にする。

このスケーリング変換で結果がゼロになった場合に
「1」に置き換える処理は入れたのだが、
「255」を超えた時の処理は入れていなかった。
(ちなみにスケーリング元の最大値は輝度テーブルの121だから
指定Q値を23以下にすると255を超える成分が出て来る。
Qを23以下に指定することなんて…ある?)

で、255を超えた時にどうなってしまうかと言うと
下位8bitだけを抜き出してUnsigned Charにキャストするので
例えばQ=1でスケーリングすると量子化テーブルは
ALL 255ではなく



となってしまう。

具体的にどこをどう直すのかと言うと・・・
Adj_Head()ファンクションの以下の青文字部分

/*****
Adjust Jpeg Header
*****/
void Adj_Head
    (long *Pic_W, long *Pic_H, unsigned char *QC){

    int i;
    long N;

//  ***** Apply Quantize Coefficient *****
    if (*QC != 50) {
        N = (*QC < 50) ? 5000 / *QC : 200 - (*QC * 2);
        for (i = 0; i < 64; i++){
            JPHead[25 + i] = (unsigned char)((N * JPHead[25 + i] + 50) / 100);
            if (JPHead[25 + i] < 1) JPHead[25 + i] = 1;
            JPHead[94 + i] = (unsigned char)((N * JPHead[94 + i] + 50) / 100);
            if (JPHead[94 + i] < 1) JPHead[94 + i] = 1;
        }
    }
<以下省略>

下のように直す。

/*****
Adjust Jpeg Header
*****/
void Adj_Head
    (long *Pic_W, long *Pic_H, unsigned char *QC){

    int i;
    long M, N;

//  ***** Apply Quantize Coefficient *****
    if (*QC != 50) {
        N = (*QC < 50) ? 5000 / *QC : 200 - (*QC * 2);
        for (i = 0; i < 64; i++){
            M = (N * JPHead[25 + i] + 50) / 100;
            if (M != 0 && M < 256) JPHead[25 + i] = (unsigned char)M;
            else if (M == 0) JPHead[25 + i] = 1;
            else JPHead[25 + i] = 255;

            M = (N * JPHead[94 + i] + 50) / 100;
            if (M != 0 && M < 256) JPHead[94 + i] = (unsigned char)M;
            else if (M == 0) JPHead[94 + i] = 1;
            else JPHead[94 + i] = 255;
        }
    }
<以下省略>

これでヨシっ!と思っていたら・・・
もう一箇所問題に気が付いた。
あぅ~ (ToT;

- つづく -



最新の画像もっと見る

コメントを投稿

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