All-About調査室 Annex

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

JFIF標準準拠のヘッダを作る のさらなる続き

2018-02-10 13:12:17 | 4:4:4 Jpeg保存dll作成

Jpegヘッダの雛形は前回完成した。
モチロン雛形に過ぎないので、コレを使うには実際の画像に合わせて
記述の一部を変更しなければならない。

具体的には
・輝度・色差双方の量子化係数テーブルを指定されたQ値でスケーリング
・タテ・ヨコの画像ピクセル数
・リスタートマーカの挿入インターバルブロック数
を修正するファンクションのコードを作る。

ヘッダを修正する関数をAdj_Head()と言う名前で
Sub Functionsセクションに以下を記述する。

<バグを見つけたのでこちらで修正しました(2018.5.11)>
///// Sub Functions /////

/*****
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;
        }
    }

//  ***** Set Picture Size *****
// Height
    JPHead[163] = (unsigned char)((*Pic_H & 0x0000FF00) >> 8);
    JPHead[164] = (unsigned char)(*Pic_H & 0x000000FF);
// Width 
    JPHead[165] = (unsigned char)((*Pic_W & 0x0000FF00) >> 8);
    JPHead[166] = (unsigned char)(*Pic_W & 0x000000FF);

//  ***** Set Interval Blocks *****
    N = (*Pic_W + 7) / 8;
    JPHead[397] = (unsigned char)((N & 0x0000FF00) >> 8);
    JPHead[398] = (unsigned char)(N & 0x000000FF);
}

GIMPで見本Jpegを吐き出させるときに品質(Q値)を50としたので
量子化係数テーブルにはIJGのQ=50での係数が記述されている。
量子化係数値のスケーリングはこの記述値を利用して変換・書き換えする。
(モチロン量子化処理ではココを参照する方針)

なお、リスタートマーカは水平方向1段分のブロックを処理するごとに
挿入することを仕様としてインターバルの値を算出・設定している。

関数は戻り値なし(Void)で良いだろう。
画像幅:Pic_Wと画像高:Pic_HはLong(32bit整数)で、
量子化係数Q値:QCは符号無しChar(符号無し8bit整数)で
このJpeg保存dllを呼び出すときに引数で指定されることを前提とする。
(DEFファイルでSJP444名でExportしているから、
“SJP444(・・・, Pic_W, Pic_H, QC,・・・)”のカタチで呼び出すってコト)


さてヘッダの次はどこ作ろう?



最新の画像もっと見る

コメントを投稿

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