見出し画像

解説クラスCopyClear(32)

解説クラスCopyClear(32)


2025年2月18初稿(初講)

この解説は、膨大なクラス「class CopyClear」の定義を
記載したファイル「CopyClear.h」の順番に従い解説して
行く為に今回は、「private:属性」の関数の説明を行う
事にします!今回は「convert_b_b_x()」関数≒LUT処理
の実働関数から説明します!
この解説文章は、
解説『解説クラスCopyClear(31)』の続きです

(4-15-52)関数「void convert_b_b_x(BYTE* ps,
BYTE* pd,BYTE lut[],int h){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→1バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_b_b_x(
    BYTE        *ps,                            // S配列実Ptr
    BYTE        *pd,                            // D配列実Ptr
    BYTE        lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_b_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_b_b_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_b_x()」の【仮引数】

void            CopyClear::convert_b_b_x(
    BYTE        *ps,                            // S配列実Ptr
    BYTE        *pd,                            // D配列実Ptr
    BYTE        lut[],                          // LUT
    int         h                               // 水平幅
){

「BYTE* ps,」は、S(元)画像画素処理ポインタ
「BYTE* pd,」は、D(結果)画像画素処理ポインタ
「BYTE lut[],」は、LUTルックアップテーブル
「int h」は、水平幅

(D)関数「convert_b_b_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-53)関数「void convert_b_b_y(
TypeArray* ps,TypeArray* pd,
BYTE lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→1バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_b_b_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    BYTE        lut[]                               // LUT
){
    BYTE        *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_b_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!
★備考★サブルーチン関数「convert_b_b_x()」を垂直方向
に繰り返す事で1バイト単位画像全体を2次元的に処理!

(B)関数「void convert_b_b_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_b_y()」の【仮引数】

void            CopyClear::convert_b_b_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    BYTE        lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「BYTE lut[]」は、LUTルックアップテーブル

(D)関数「convert_b_b_y()」の【アルゴリズム】

){
    BYTE        *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    BYTE        *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「BYTE* ptrs;」は、S(元)画像画素アクセスポインタ
「BYTE* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(BYTE*)ps->adr;ptrd=(BYTE*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_b_b_x(ptrs,ptrd,lut,hv);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_b_b_x(ptrs,ptrd,lut,hv);」とサブルーチン
関数「convert_b_b_x()」で処理します!
「else{while(--v>=0){convert_b_b_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_b_b_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_b_b_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-54)関数「int convert_b_b(
TypeArray* ps,TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:1バイト→LUT→1バイト              *****/
/************************************************************************/

int             CopyClear::convert_b_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    BYTE        buf[ 0x100 ];                       // バッファー
    BYTE        *plut;                              // LUTへのPtr

    plut = MoveArrayByte( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_b_y( ps, pd, plut );                  // LUT変換:1→1垂直
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_b();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!
★備考★サブルーチン関数「convert_b_b_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_b_b();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b_b()」の【仮引数】

int             CopyClear::convert_b_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b_b()」の【アルゴリズム】

){
    BYTE        buf[ 0x100 ];                       // バッファー
    BYTE        *plut;                              // LUTへのPtr

    plut = MoveArrayByte( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_b_y( ps, pd, plut );                  // LUT変換:1→1垂直
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    BYTE        buf[ 0x100 ];                       // バッファー
    BYTE        *plut;                              // LUTへのPtr

「BYTE buf[0x100];」は、ローカルバッファー
「BYTE* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    plut = MoveArrayByte( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_b_y( ps, pd, plut );                  // LUT変換:1→1垂直
    return( END_STI );                              // 正常終了 
}

「plut=MoveArrayByte(lut,buf,0x100);」は、バッファー
へLUTデータをコピー
「if(plut==0){return(STI_ARY_5-20);}」は、もし、
エラー≪コピー出来無い時≫が有ればエラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray*型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_b_b_y(ps,pd,plut);」は、サブルーチン関数
「convert_b_b_y()」で二次元配列的に画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-55)関数「void convert_b_s_x(BYTE* ps,
short* pd,short lut[],int h){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→2バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_b_s_x(
    BYTE        *ps,                            // S配列実Ptr
    short       *pd,                            // D配列実Ptr
    short       lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_s_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_b_s」で「BYTE型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_b_s_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_s_x()」の【仮引数】

void            CopyClear::convert_b_s_x(
    BYTE        *ps,                            // S配列実Ptr
    short       *pd,                            // D配列実Ptr
    short       lut[],                          // LUT
    int         h                               // 水平幅
){

「BYTE* ps,」は、S(元)画像画素処理ポインタ
「short* pd,」は、D(結果)画像画素処理ポインタ
「short lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「short* pd,」と「short lut[],」と型が同じ事
に注意!

(D)関数「convert_b_s_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-56)関数「void convert_b_s_y(
TypeArray* ps,
TypeArray* pd,short lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→2バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_b_s_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    short       lut[]                               // LUT
){
    BYTE        *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_s_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_b_s」で「BYTE型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_b_s_x()」を垂直方向
に繰り返す事で1バイト単位画像全体を2次元的に処理!

(B)関数「void convert_b_s_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_s_y()」の【仮引数】

void            CopyClear::convert_b_s_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    short       lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「short lut[]」は、LUTルックアップテーブル

(D)関数「convert_b_s_y()」の【アルゴリズム】

){
    BYTE        *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    BYTE        *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「BYTE* ptrs;」は、S(元)画像画素アクセスポインタ
「short* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(BYTE*)ps->adr;ptrd=(short*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_b_s_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_b_s_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_b_s_x()」で処理します!
「else{while(--v>=0){convert_b_s_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_b_s_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_b_s_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-57)関数「int convert_b_s(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:1バイト→LUT→2バイト              *****/
/************************************************************************/

int             CopyClear::convert_b_s(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    short       buf[ 0x100 ];                       // バッファー
    short       *plut;                              // LUTへのPtr

    plut = MoveArrayShort( lut, buf, 0x100 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_s_y( ps, pd, plut );                  // LUT変換:1→2垂直
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_s();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_b_s」で「BYTE型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
★備考★サブルーチン関数「convert_b_s_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_b_s();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b_s()」の【仮引数】

int             CopyClear::convert_b_s(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b_s()」の【アルゴリズム】

){
    short       buf[ 0x100 ];                       // バッファー
    short       *plut;                              // LUTへのPtr

    plut = MoveArrayShort( lut, buf, 0x100 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_s_y( ps, pd, plut );                  // LUT変換:1→2垂直
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    short       buf[ 0x100 ];                       // バッファー
    short       *plut;                              // LUTへのPtr

「short buf[0x100];」は、ローカルバッファー
「short* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    plut = MoveArrayShort( lut, buf, 0x100 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_s_y( ps, pd, plut );                  // LUT変換:1→2垂直
    return( END_STI );                              // 正常終了 
}

「plut=MoveArrayShort(lut,buf,0x100);」は、バッファー
へLUTデータをコピー
「if(plut==0){return(STI_ARY_5-20);}」は、もし、
エラー≪コピー出来無い時≫が有ればエラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray*型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_b_s_y(ps,pd,plut);」は、サブルーチン関数
「convert_b_s_y()」で二次元配列的に画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-58)関数「void convert_b_l_x(BYTE *ps,
long *pd,long lut[],int h);」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→4バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_b_l_x(
    BYTE        *ps,                            // S配列実Ptr
    long        *pd,                            // D配列実Ptr
    long        lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_l_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_b_l」で「BYTE型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_b_l_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_l_x()」の【仮引数】

void            CopyClear::convert_b_l_x(
    BYTE        *ps,                            // S配列実Ptr
    long        *pd,                            // D配列実Ptr
    long        lut[],                          // LUT
    int         h                               // 水平幅
){

「BYTE* ps,」は、S(元)画像画素処理ポインタ
「long* pd,」は、D(結果)画像画素処理ポインタ
「long lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「long* pd,」と「long lut[],」と型が同じ事
に注意!

(D)関数「convert_b_l_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-59)関数「void convert_b_l_y(
TypeArray* ps,TypeArray* pd,
long lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→4バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_b_l_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    long        lut[]                               // LUT
){
    BYTE        *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_l_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_b_s」で「BYTE型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_b_l_x()」を垂直方向
に繰り返す事で1バイト単位画像全体を2次元的に処理!

(B)関数「void convert_b_l_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_l_y()」の【仮引数】

void            CopyClear::convert_b_l_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    long        lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「long lut[]」は、LUTルックアップテーブル

(D)関数「convert_b_l_y()」の【アルゴリズム】

){
    BYTE        *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    BYTE        *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「BYTE* ptrs;」は、S(元)画像画素アクセスポインタ
「long* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(BYTE*)ps->adr;ptrd=(long*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_b_l_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_b_l_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_b_l_x()」で処理します!
「else{while(--v>=0){convert_b_l_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_b_l_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_b_l_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-60)関数「int convert_b_l(
TypeArray* ps,TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:1バイト→LUT→4バイト              *****/
/************************************************************************/

int             CopyClear::convert_b_l(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    long        buf[ 0x100 ];                       // バッファー
    long        *plut;                              // LUTへのPtr

    plut = MoveArrayLong( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_l_y( ps, pd, plut );                  // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_l();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_b_l」で「BYTE型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
★備考★サブルーチン関数「convert_b_l_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_b_l();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b_l()」の【仮引数】

int             CopyClear::convert_b_l(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b_l()」の【アルゴリズム】

){
    long        buf[ 0x100 ];                       // バッファー
    long        *plut;                              // LUTへのPtr

    plut = MoveArrayLong( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_l_y( ps, pd, plut );                  // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    long        buf[ 0x100 ];                       // バッファー
    long        *plut;                              // LUTへのPtr

「long buf[0x100];」は、ローカルバッファー
「long* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    plut = MoveArrayLong( lut, buf, 0x100 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_l_y( ps, pd, plut );                  // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

「plut=MoveArraylong(lut,buf,0x100);」は、バッファー
へLUTデータをコピー
「if(plut==0){return(STI_ARY_5-20);}」は、もし、
エラー≪コピー出来無い時≫が有ればエラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray*型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_b_l_y(ps,pd,plut);」は、サブルーチン関数
「convert_b_l_y()」で二次元配列的に画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-61)関数「void convert_b_f_x(BYTE *ps,float *pd,float lut[],int h);」

☆備考☆この関数の実体は存在しません!
ヘッダファイル「CopyClear.h」に定義として記載していま
すが、必要無かったので残骸だけ残った形です!

(4-15-62)関数「void convert_b_l_y(TypeArray* ps,TypeArray* pd,float lut[]){・・・}」

☆備考☆この関数の実体は存在しません!
ヘッダファイル「CopyClear.h」に定義として記載していま
すが、必要無かったので残骸だけ残った形です!

(4-15-63)関数「int convert_b_f(TypeArray* ps,TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:1バイト→LUT→単精度                *****/
/************************************************************************/

int             CopyClear::convert_b_f(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    float       buf[ 0x100 ];                       // バッファー
    float       *plut;                              // LUTへのptr

    plut = MoveArrayFloat( lut, buf, 0x100 );       // BufへCOPY
    convert_b_l_y( ps, pd, (long*)plut );           // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_f();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_b」は、「BYTE型」詰り1バイト単位を意味!
「_f」は、「long型」詰り4バイト単位を意味!
「_b_f」で「BYTE型」の画素から「float型」のLUTを
使用して「float型」詰り4バイト単位作成です!
★備考★サブルーチン関数「convert_b_f_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_b_f();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b_f()」の【仮引数】

int             CopyClear::convert_b_f(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b_f()」の【アルゴリズム】

){
    float       buf[ 0x100 ];                       // バッファー
    float       *plut;                              // LUTへのptr

    plut = MoveArrayFloat( lut, buf, 0x100 );       // BufへCOPY
    convert_b_l_y( ps, pd, (long*)plut );           // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    float       buf[ 0x100 ];                       // バッファー
    float       *plut;                              // LUTへのptr

「float buf[0x100];」は、ローカルバッファー
「float* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    plut = MoveArrayFloat( lut, buf, 0x100 );       // BufへCOPY
    convert_b_l_y( ps, pd, (long*)plut );           // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

「plut=MoveArrayFloat(lut,buf,0x100);」は、バッファー
へLUTデータをコピー
「convert_b_l_y(ps,pd,(long*)plut);」は、サブルーチン
関数「convert_b_l_y()」で4バイト整数型二次元配列的に
画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!
★備考★単精度浮動小数点型「float」も整数型「long」も
4バイトデータなので流用して使用している事に注意!

(4-15-64)関数「void convert_b_d_x(BYTE *ps,double *pd,double lut[],int h);」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→倍精度:水平方向              *****/
/************************************************************************/

void            CopyClear::convert_b_d_x(
    BYTE        *ps,                            // S配列実Ptr
    double      *pd,                            // D配列実Ptr
    double      lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_d_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_d」は、「double型」詰り倍精度浮動小数点型単位を
意味!
「_b_d」で「BYTE型」の画素から「double型」のLUTを
使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_b_d_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_d_x()」の【仮引数】

void            CopyClear::convert_b_d_x(
    BYTE        *ps,                            // S配列実Ptr
    double      *pd,                            // D配列実Ptr
    double      lut[],                          // LUT
    int         h                               // 水平幅
){

「BYTE* ps,」は、S(元)画像画素処理ポインタ
「double* pd,」は、D(結果)画像画素処理ポインタ
「double lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「double* pd,」と「double lut[],」と型が同じ事
に注意!

(D)関数「convert_b_d_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-65)関数「void convert_b_d_y(
TypeArray* ps,TypeArray* pd,double lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:1バイト→LUT→倍精度:垂直方向              *****/
/************************************************************************/

void            CopyClear::convert_b_d_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    double      lut[]                               // LUT
){
    BYTE        *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_d_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_d」は、「double型」詰り、「double型」詰り倍精度
浮動小数点型単位を意味!
「_b_s」で「BYTE型」の画素から「double型」のLUTを
使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_b_d_x()」を垂直方向
に繰り返す事で1バイト単位画像全体を2次元的に処理!

(B)関数「void convert_b_d_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_b_d_y()」の【仮引数】

void            CopyClear::convert_b_d_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    double      lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「double lut[]」は、LUTルックアップテーブル

(D)関数「convert_b_d_y()」の【アルゴリズム】

){
    BYTE        *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    BYTE        *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「BYTE* ptrs;」は、S(元)画像画素アクセスポインタ
「double* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (BYTE*)ps->adr;                         // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_b_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_b_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(BYTE*)ps->adr;ptrd=(double*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_b_d_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_b_d_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_b_d_x()」で処理します!
「else{while(--v>=0){convert_b_d_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_b_d_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_b_d_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-66)関数「int convert_b_d(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

int             CopyClear::convert_b_d(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b_d();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_d」は、「double型」詰り、「double型」詰り倍精度
浮動小数点型単位を意味!
「_b_s」で「BYTE型」の画素から「double型」のLUTを
使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
★備考★サブルーチン関数「convert_b_d_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_b_d();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b_d()」の【仮引数】

int             CopyClear::convert_b_d(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b_d()」の【アルゴリズム】

){
    double      buf[ 0x100 ];                       // バッファー
    double      *plut;                              // LUTへのPtr

    plut = MoveArrayDouble( lut, buf, 0x100 );      // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_d_y( ps, pd, plut );                  // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    double      buf[ 0x100 ];                       // バッファー
    double      *plut;                              // LUTへのPtr

「long buf[0x100];」は、ローカルバッファー
「long* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    plut = MoveArrayDouble( lut, buf, 0x100 );      // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_b_d_y( ps, pd, plut );                  // LUT変換:1→4垂直
    return( END_STI );                              // 正常終了 
}

「plut=MoveArrayDouble(lut,buf,0x100);」は、
バッファーへLUTデータをコピー
「if(plut==0){return(STI_ARY_5-20);}」は、もし、
エラー≪コピー出来無い時≫が有ればエラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray*型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_b_d_y(ps,pd,plut);」は、サブルーチン関数
「convert_b_d_y()」で二次元配列的に画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-67)関数「int convert_b(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換コマンド              :S=BYTEの時          *****/
/*****  CONVERT,s,d[,LUT]                          *****/
/************************************************************************/

int             CopyClear::convert_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT配列
){
    switch( pd->w ){                                // Dの処理幅が
    case 1:                                         // 1バイト単位なら
        return( convert_b_b( ps, pd, lut ) );       // 左記でLUT変換
    case 2:                                         // 2バイト単位なら
        return( convert_b_s( ps, pd, lut ) );       // 左記でLUT変換
    case 4:                                         // 4バイト整数か
        return( convert_b_l( ps, pd, lut ) );       // 左記でLUT変換
    case 101:                                       // 単精度単位なら
        return( convert_b_f( ps, pd, lut ) );       // 左記でLUT変換
    case 102:                                       // 倍精度単位なら
        return( convert_b_d( ps, pd, lut ) );       // 左記でLUT変換
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 20 );                   // 不正を返す
    }                                               //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_b();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_b」は、「BYTE型」詰り1バイト単位を意味!
★備考★S(元)画像が1バイト単位でのLUT変換
関数です!

(B)関数「int convert_b();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_b()」の【仮引数】

int             CopyClear::convert_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT配列
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_b()」の【アルゴリズム】

){
    switch( pd->w ){                                // Dの処理幅が
    case 1:                                         // 1バイト単位なら
        return( convert_b_b( ps, pd, lut ) );       // 左記でLUT変換
    case 2:                                         // 2バイト単位なら
        return( convert_b_s( ps, pd, lut ) );       // 左記でLUT変換
    case 4:                                         // 4バイト整数か
        return( convert_b_l( ps, pd, lut ) );       // 左記でLUT変換
    case 101:                                       // 単精度単位なら
        return( convert_b_f( ps, pd, lut ) );       // 左記でLUT変換
    case 102:                                       // 倍精度単位なら
        return( convert_b_d( ps, pd, lut ) );       // 左記でLUT変換
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 20 );                   // 不正を返す
    }                                               //
}

概要「switch(pd->w){・・switch分岐本体・・}」で
D(結果)画像の画素単位が
「case 1:return(convert_b_b(ps,pd,lut));」と1バイト
整数型ならば、「return(convert_b_b(ps,pd,lut));」で
サブルーチン関数「convert_b_b()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 2:return(convert_b_s(ps,pd,lut));」と2バイト
整数型ならば、「return(convert_b_s(ps,pd,lut));」で
サブルーチン関数「convert_b_s()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 4:return(convert_b_l(ps,pd,lut));」と4バイト
整数型ならば、「return(convert_b_l(ps,pd,lut));」で
サブルーチン関数「convert_b_l()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 101:return(convert_b_f(ps,pd,lut));」と単精度
浮動小数点型ならば「return(convert_b_f(ps,pd,lut));」
でサブルーチン関数「convert_b_f()」で処理し、この関数
の関数辺値を関数辺値とし返し関数終了!
「case 102:return(convert_b_d(ps,pd,lut));」と単精度
浮動小数点型ならば「return(convert_b_d(ps,pd,lut));」
でサブルーチン関数「convert_b_d()」で処理し、この関数
の関数辺値を関数辺値とし返し関数終了!
「default:return(STI_ARY_5-20);」は、画素単位を示す
値が対象外とし、エラーコード「STI_ARY_5-20」を返し
関数終了!

(4-15-68)関数「void convert_w_b_x(UWORD* ps,
BYTE* pd,BYTE lut[],int h){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→1バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_w_b_x(
    UWORD       *ps,                            // S配列実Ptr
    BYTE        *pd,                            // D配列実Ptr
    BYTE        lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_b_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_w_b」で「UWORD型」の画素から「BYTE型」のLUTを
使用して「BYTE型」詰り1バイト単位作成です!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_w_b_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_b_x()」の【仮引数】

void            CopyClear::convert_w_b_x(
    UWORD       *ps,                            // S配列実Ptr
    BYTE        *pd,                            // D配列実Ptr
    BYTE        lut[],                          // LUT
    int         h                               // 水平幅
){

「UWORD* ps,」は、S(元)画像画素処理ポインタ
「BYTE* pd,」は、D(結果)画像画素処理ポインタ
「BYTE lut[],」は、LUTルックアップテーブル
「int h」は、水平幅

(D)関数「convert_w_b_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-69)関数「void convert_w_b_y(TypeArray* ps,TypeArray* pd,BYTE lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→1バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_w_b_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    BYTE        lut[]                               // LUT
){
    UWORD       *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_b_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_w」は、「UWORD型」詰り2バイト単位を意味!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_w_b」で「UWORD型」から「BYTE型」への変換です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!
★備考★サブルーチン関数「convert_w_b_x()」を垂直方向
に繰り返す事で1バイト単位画像全体を2次元的に処理!

(B)関数「void convert_w_b_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_b_y()」の【仮引数】

void            CopyClear::convert_w_b_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    BYTE        lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「BYTE lut[]」は、LUTルックアップテーブル

(D)関数「convert_w_b_y()」の【アルゴリズム】

){
    UWORD       *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    UWORD       *ptrs;                              // S配列実Ptr
    BYTE        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「UWORD* ptrs;」は、S(元)画像画素アクセスポインタ
「BYTE* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (BYTE*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_b_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_b_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(UWORD*)ps->adr;ptrd=(BYTE*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_w_b_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_w_b_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_w_b_x()」で処理します!
「else{while(--v>=0){convert_w_b_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_w_b_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_w_b_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-70)関数「int convert_w_b(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:2バイト→LUT→1バイト              *****/
/************************************************************************/

int             CopyClear::convert_w_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    BYTE        *buf;                               // バッファー
    BYTE        *plut;                              // LUTへのPtr

    buf = (BYTE*)malloc( sizeof(BYTE) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayByte( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_b_y( ps, pd, plut );                  // LUT変換:2→1垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_b();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_w」は、「UWORD型」詰り2バイト単位を意味!
「_b」は、「BYTE型」詰り1バイト単位を意味!
「_w_b」で「UWORD型」から「BYTE型」への変換です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!
★備考★サブルーチン関数「convert_w_b_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_w_b();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w_b()」の【仮引数】

int             CopyClear::convert_w_b(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w_b()」の【アルゴリズム】

){
    BYTE        *buf;                               // バッファー
    BYTE        *plut;                              // LUTへのPtr

    buf = (BYTE*)malloc( sizeof(BYTE) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayByte( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_b_y( ps, pd, plut );                  // LUT変換:2→1垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    BYTE        *buf;                               // バッファー
    BYTE        *plut;                              // LUTへのPtr

「BYTE* buf;」は、ローカルバッファー(取得ポインタ)
「BYTE* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    buf = (BYTE*)malloc( sizeof(BYTE) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayByte( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_b_y( ps, pd, plut );                  // LUT変換:2→1垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

「buf=(BYTE*)malloc(sizeof(BYTE)*65536);」は、動的に
メモリ確保★備考★昔は65536サイズの配列で確保する
事がコンパイルシステムで許可出来無かったシステムが多か
ったのです!
「if(buf==0){return(STI_MEM);}」は、動的確保に失敗
したら、エラーコード「STI_MEM」を関数辺値とし返し、
関数終了!
「plut=MoveArrayByte(lut,buf,65536);」は、
バッファーへLUTデータをコピー
「if(plut==0){free(buf);return(STI_ARY_5-20);}」は、
もし、エラー≪コピー出来無い時≫が有れば、後始末
「free(buf);」とし確保メモリ解放し、エラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_w_b_y(ps,pd,plut);」は、サブルーチン関数
「convert_w_b_y()」で二次元配列的に画像を処理!
「free(buf);」は、後始末としてメモリ解放処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-71)関数「void convert_w_s_x(UWORD* ps,short* pd,short lut[],int h){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→2バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_w_s_x(
    UWORD       *ps,                            // S配列実Ptr
    short       *pd,                            // D配列実Ptr
    short       lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_s_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_w_s」で「UWORD型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_w_s_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_s_x()」の【仮引数】

void            CopyClear::convert_w_s_x(
    UWORD       *ps,                            // S配列実Ptr
    short       *pd,                            // D配列実Ptr
    short       lut[],                          // LUT
    int         h                               // 水平幅
){

「UWORD* ps,」は、S(元)画像画素処理ポインタ
「short* pd,」は、D(結果)画像画素処理ポインタ
「short lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「short* pd,」と「short lut[],」と型が同じ事
に注意!

(D)関数「convert_w_s_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-72)関数「void convert_w_s_y(
TypeArray* ps,
TypeArray* pd,short lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→2バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_w_s_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    short       lut[]                               // LUT
){
    UWORD       *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_s_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_w_s」で「UWORD型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_w_s_x()」を垂直方向
に繰り返す事で2バイト単位画像全体を2次元的に処理!

(B)関数「void convert_w_s_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_s_y()」の【仮引数】

void            CopyClear::convert_w_s_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    short       lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「short lut[]」は、LUTルックアップテーブル

(D)関数「convert_w_s_y()」の【アルゴリズム】

){
    UWORD       *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    UWORD       *ptrs;                              // S配列実Ptr
    short       *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「UWORD* ptrs;」は、S(元)画像画素アクセスポインタ
「short* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (short*)pd->adr;                        // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_s_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_s_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(UWORD*)ps->adr;ptrd=(short*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_w_s_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_w_s_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_w_s_x()」で処理します!
「else{while(--v>=0){convert_w_s_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_w_s_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_w_s_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-73)関数「int convert_w_s(TypeArray* ps,TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:2バイト→LUT→2バイト              *****/
/************************************************************************/

int             CopyClear::convert_w_s(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    short       *buf;                               // バッファー
    short       *plut;                              // LUTへのPtr

    buf = (short*)malloc( sizeof(short) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayShort( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_s_y( ps, pd, plut );                  // LUT変換:2→2垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_s();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_w」は、「UWORD型」詰り2バイト単位を意味!
「_s」は、「short型」詰り2バイト単位を意味!
「_w_s」で「BYTE型」の画素から「short型」のLUTを
使用して「short型」詰り2バイト単位作成です!
★備考★サブルーチン関数「convert_w_s_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_w_s();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w_s()」の【仮引数】

int             CopyClear::convert_w_s(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w_s()」の【アルゴリズム】

){
    short       *buf;                               // バッファー
    short       *plut;                              // LUTへのPtr

    buf = (short*)malloc( sizeof(short) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayShort( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_s_y( ps, pd, plut );                  // LUT変換:2→2垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    short       *buf;                               // バッファー
    short       *plut;                              // LUTへのPtr

「short* buf;」は、ローカルバッファー(取得ポインタ)
「short* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    buf = (short*)malloc( sizeof(short) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayShort( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_s_y( ps, pd, plut );                  // LUT変換:2→2垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

「buf=(short*)malloc(sizeof(short)*65536);」は、
バッファーのメモリ動的確保!★備考★昔は65536サイズの配列で確保する
事がコンパイルシステムで許可出来無かったシステムが多か
ったのです!
「if(buf==0){return(STI_MEM);}」は、確保失敗したら、
エラーコード「STI_MEM」を関数辺値とし返し関数終了!
「plut=MoveArrayShort(lut,buf,65536);」は、バッファー
へLUTデータをコピー
「if(plut==0){free(buf);return(STI_ARY_5-20);}」は、
もし、エラー≪コピー出来無い時≫が有れば、後始末
「free(buf);」とし確保メモリ解放し、エラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_w_s_y(ps,pd,plut);」は、サブルーチン関数
「convert_w_s_y()」で二次元配列的に画像を処理!
「free(buf);」は、後始末とし確保メモリ解放!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-74)関数「void convert_w_l_x(UWORD* ps,long* pd,long lut[],int h){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→4バイト:水平方向            *****/
/************************************************************************/

void            CopyClear::convert_w_l_x(
    UWORD       *ps,                            // S配列実Ptr
    long        *pd,                            // D配列実Ptr
    long        lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_l_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_w_l」で「UWORD型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_w_l_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_l_x()」の【仮引数】

void            CopyClear::convert_w_l_x(
    UWORD       *ps,                            // S配列実Ptr
    long        *pd,                            // D配列実Ptr
    long        lut[],                          // LUT
    int         h                               // 水平幅
){

「UWORD* ps,」は、S(元)画像画素処理ポインタ
「long* pd,」は、D(結果)画像画素処理ポインタ
「long lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「long* pd,」と「long lut[],」と型が同じ事
に注意!

(D)関数「convert_w_l_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ「int d2;」は、同上2番目画素データ「int d3;」は、同上3番目画素データ「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-75)関数「void convert_w_l_y(
TypeArray* ps,TypeArray* pd,
long lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→4バイト:垂直方向            *****/
/************************************************************************/

void            CopyClear::convert_w_l_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    long        lut[]                               // LUT
){
    UWORD       *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_l_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_w_l」で「UWORD型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_w_l_x()」を垂直方向
に繰り返す事で2バイト単位画像全体を2次元的に処理!

(B)関数「void convert_w_l_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_l_y()」の【仮引数】

void            CopyClear::convert_w_l_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    long        lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「long lut[]」は、LUTルックアップテーブル

(D)関数「convert_w_l_y()」の【アルゴリズム】

){
    UWORD       *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    UWORD       *ptrs;                              // S配列実Ptr
    long        *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「UWORD* ptrs;」は、S(元)画像画素アクセスポインタ
「long* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_l;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (long*)pd->adr;                         // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_l_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_l_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(UWORD*)ps->adr;ptrd=(long*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_w_l_x(ptrs,ptrd,lut,h*v);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_w_l_x(ptrs,ptrd,lut,h*v);」とサブルーチン
関数「convert_w_l_x()」で処理します!
「else{while(--v>=0){convert_w_l_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_w_l_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_w_l_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-76)関数「int convert_w_l(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:2バイト→LUT→4バイト              *****/
/************************************************************************/

int             CopyClear::convert_w_l(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    long        *buf;                               // バッファー
    long        *plut;                              // LUTへのPtr

    buf = (long*)malloc( sizeof(long) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayLong( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, plut );                  // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_l();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_w」は、「UWORD型」詰り2バイト単位を意味!
「_l」は、「long型」詰り4バイト単位を意味!
「_w_l」で「BYTE型」の画素から「long型」のLUTを
使用して「long型」詰り4バイト単位作成です!
★備考★サブルーチン関数「convert_w_l_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_w_l();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w_l()」の【仮引数】

int             CopyClear::convert_w_l(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w_l()」の【アルゴリズム】

){
    long        *buf;                               // バッファー
    long        *plut;                              // LUTへのPtr

    buf = (long*)malloc( sizeof(long) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayLong( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, plut );                  // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    long        *buf;                               // バッファー
    long        *plut;                              // LUTへのPtr

「long* buf;」は、ローカルバッファー(取得ポインタ)
「long* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    buf = (long*)malloc( sizeof(long) * 65536 );    // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayLong( lut, buf, 65536 );        // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, plut );                  // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

「buf=(long*)malloc(sizeof(long)*65536);」は、
バッファーのメモリ動的確保!★備考★昔は65536サイズの配列で確保する
事がコンパイルシステムで許可出来無かったシステムが多か
ったのです!
「if(buf==0){return(STI_MEM);}」は、確保失敗したら、
エラーコード「STI_MEM」を関数辺値とし返し関数終了!
「plut=MoveArrayLong(lut,buf,65536);」は、バッファー
へLUTデータをコピー
「if(plut==0){free(buf);return(STI_ARY_5-20);}」は、
もし、エラー≪コピー出来無い時≫が有れば、後始末
「free(buf);」とし確保メモリ解放し、エラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_w_l_y(ps,pd,plut);」は、サブルーチン関数
「convert_w_l_y()」で二次元配列的に画像を処理!
「free(buf);」は、後始末とし確保メモリ解放!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-77)関数「void convert_w_f_x(UWORD *ps,float *pd,float lut[],int h);」

☆備考☆この関数の実体は存在しません!
ヘッダファイル「CopyClear.h」に定義として記載していま
すが、必要無かったので残骸だけ残った形です!

(4-15-78)関数「void convert_w_f_y(TypeArray* ps,TypeArray* pd,float lut[]){・・・}」

☆備考☆この関数の実体は存在しません!
ヘッダファイル「CopyClear.h」に定義として記載していま
すが、必要無かったので残骸だけ残った形です!

(4-15-79)関数「int convert_w_f(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:2バイト→LUT→単精度                *****/
/************************************************************************/

int             CopyClear::convert_w_f(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){
    float       *buf;                               // バッファー
    float       *plut;                              // LUTへのPtr

    buf = (float*)malloc( sizeof(float) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayFloat( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, (long*)plut );           // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_f();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!「_w」は、「UWORD型」詰り4バイト単位を意味!
「_f」は、「float型」詰り単精度浮動小数点型単位を
意味!
「_w_f」で「UWORD型」の画素から「float型」のLUTを
使用して「float型」詰り単精度浮動小数点型単位作成
です!
★備考★サブルーチン関数「convert_w_l_y()」を使用して
4バイト整数型と単精度浮動小数点型が4バイトで有る事で
処理する関数です!

(B)関数「int convert_w_f();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w_f()」の【仮引数】

int             CopyClear::convert_w_f(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w_f()」の【アルゴリズム】

){
    float       *buf;                               // バッファー
    float       *plut;                              // LUTへのPtr

    buf = (float*)malloc( sizeof(float) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayFloat( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, (long*)plut );           // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

(D-1)ローカル変数

){
    float       *buf;                               // バッファー
    float       *plut;                              // LUTへのPtr

「float* buf」は、ローカルバッファー
「float* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    buf = (float*)malloc( sizeof(float) * 65536 );  // メモリ確保
    if( buf == 0 ){                                 // 失敗時
        return( STI_MEM );                          // 左記を返す
    }                                               // 
    plut = MoveArrayFloat( lut, buf, 65536 );       // BufへCOPY
    if( plut == 0 ){                                // 失敗時は、
        free( buf );                                // メモリ解放し
        return( STI_ARY_5 - 20 );                   // 2番引数ERR
    }                                               // 
    convert_w_l_y( ps, pd, (long*)plut );           // LUT変換:2→4垂直
    free( buf );                                    // メモリ解放し
    return( END_STI );                              // 正常終了 
}

「buf=(float*)malloc(sizeof(float)*65536);」は、
バッファーのメモリ動的確保!★備考★昔は65536サイズの配列で確保する
事がコンパイルシステムで許可出来無かったシステムが多か
ったのです!
「if(buf==0){return(STI_MEM);}」は、確保失敗したら、
エラーコード「STI_MEM」を関数辺値とし返し関数終了!
「plut=MoveArrayFloat(lut,buf,65536);」は、バッファー
へLUTデータをコピー
「if(plut==0){free(buf);return(STI_ARY_5-20);}」は、
もし、エラー≪コピー出来無い時≫が有れば、後始末
「free(buf);」とし確保メモリ解放し、エラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_w_l_y(ps,pd,(long*)plut);」は、サブルーチン
関数「convert_w_l_y()」で4バイト整数型二次元配列的に
画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!
★備考★単精度浮動小数点型「float」も整数型「long」も
4バイトデータなので流用して使用している事に注意!

(4-15-80)関数「void convert_w_d_x(UWORD *ps,
double *pd,double lut[],int h);」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→倍精度:水平方向              *****/
/************************************************************************/

void            CopyClear::convert_w_d_x(
    UWORD       *ps,                            // S配列実Ptr
    double      *pd,                            // D配列実Ptr
    double      lut[],                          // LUT
    int         h                               // 水平幅
){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_d_x();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_d」は、「double型」詰り倍精度浮動小数点型単位を
意味!
「_w_d」で「UWORD型」の画素から「double型」のLUTを
使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
「_x」は、X座標方向の処理を意味!ココでは、
LUT変換のX座標方向(水平方向)の処理です!

(B)関数「void convert_w_d_x();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_d_x()」の【仮引数】

void            CopyClear::convert_w_d_x(
    UWORD       *ps,                            // S配列実Ptr
    double      *pd,                            // D配列実Ptr
    double      lut[],                          // LUT
    int         h                               // 水平幅
){

「UWORD* ps,」は、S(元)画像画素処理ポインタ
「double* pd,」は、D(結果)画像画素処理ポインタ
「double lut[],」は、LUTルックアップテーブル
「int h」は、水平幅
★備考★「double* pd,」と「double lut[],」と型が同じ事
に注意!

(D)関数「convert_w_d_x()」の【アルゴリズム】

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

(D-1)ローカル変数

){
    int         d1;                             // データ
    int         d2;                             // データ
    int         d3;                             // データ
    int         d4;                             // データ

「int d1;」は、4画素マトメ処理をする1番目画素データ
「int d2;」は、同上2番目画素データ
「int d3;」は、同上3番目画素データ
「int d4;」は、同上4番目画素データ

(D―2)アルゴリズムコード

    if( h >= 4 ){                               // 4単位以上なら
        h -= 4;                                 // DownCuntを4単位進め
        do{                                     // 4単位毎に
            d1    = *ps++;                      // LUT変換を行う
            d2    = *ps++;                      // 
            d3    = *ps++;                      // 
            d4    = *ps++;                      // 
            *pd++ = lut[ d1 ];                  // 
            *pd++ = lut[ d2 ];                  //
            *pd++ = lut[ d3 ];                  //
            *pd++ = lut[ d4 ];                  //
        }while( ( h -= 4 ) > 0 );               //
        h += 4;                                 // DownCuntを4単位戻す
    }                                           //
    while( --h >= 0 ){                          // 残りを1単位毎に
        *pd++ = lut[ *ps++ ];                   // 転送する 
    }                                           //
}

「if(h>=4){・・分岐成立・・}」は、条件「h>=4」詰り、
4画素以上水平幅が有れば、成立
「h-=4;do{・・ループ本体・・}while((h-=4)>0);」は、
「h-=4;」は、元々4以上個数が有るので4減じても0以上
の値が残る前処理、そしてdo構文とループ条件が後置≪
必ずループ本体の1っ回目は実行する≫で後置のループ条件
「(h-=4)>0」は、4減じても0を超えるので次も条件検査
可能との理屈で繰り返します!そしてループ本体は
「d1=*ps++;d2=*ps++;d3=*ps++;d4=*ps++;」と4画素分の
データをローカル変数にセット!
「*pd++=lut[d1];*pd++=lut[d2];*pd++=lut[d3];
*pd++=lut[d4];」で「lut[d1]」等とLUT変換を行い
結果画像に「*pd++=」と格納!詰り、4画素分の処理を
マトメて行います!★備考★4画素分並べるので繰り返し
構文の時間ロスが発生しません!
「h+=4;」は、★注意★「h-=4;」をループ処理を行う前に
実行しているので元の値に戻す為の処理です!これは注意
「while(--h>=0){*pd++=lut[*ps++];}」は、上記の
do構文で水平幅が4づつ減じている余り≪1~3≫の
処理で良く私のアルゴリズムで使用しているwhile条件
「--h>=0」とダウンカウンを使用して中身
「*pd++=lut[*ps++];」と1画素単位LUT変換します!
★備考★何故、4画素毎の処理かと説明すると一画素の
LUT変換「*pd++=lut[*ps++];」も結構、重い処理だから
この4画素毎が丁度良いと判断したからです!

(4-15-81)関数「void convert_w_d_y(
TypeArray* ps,
TypeArray* pd,double lut[]){・・・}」

/************************************************************************/
/*****  LUT変換:2バイト→LUT→倍精度:垂直方向              *****/
/************************************************************************/

void            CopyClear::convert_w_d_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    double      lut[]                               // LUT
){
    UWORD       *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_d_y();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_d」は、「double型」詰り、「double型」詰り倍精度
浮動小数点型単位を意味!
「_w_s」で「UWORD型」の画素から「double型」のLUTを使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
「_y」は、Y座標方向の処理を意味!ココでは、
LUT変換のY座標方向(垂直方向)の処理です!

★備考★サブルーチン関数「convert_w_d_x()」を垂直方向
に繰り返す事で2バイト単位画像全体を2次元的に処理!

(B)関数「void convert_w_d_y();」の【返値】

返値を返さない関数です!
★注意★詰り、実引数の検査を実行時に行いませんので
使用する時は、正しい実引数を記載する必要が有ります!

(C)関数「convert_w_d_y()」の【仮引数】

void            CopyClear::convert_w_d_y(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    double      lut[]                               // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「double lut[]」は、LUTルックアップテーブル

(D)関数「convert_w_d_y()」の【アルゴリズム】

){
    UWORD       *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

(D-1)ローカル変数

){
    UWORD       *ptrs;                              // S配列実Ptr
    double      *ptrd;                              // D配列実Ptr
    int         h;                                  // 水平幅
    int         v;                                  // 垂直幅
    int         inc_s;                              // 増加幅:S
    int         inc_d;                              // 増加幅:D

「UWORD* ptrs;」は、S(元)画像画素アクセスポインタ
「double* ptrd;」は、D(結果)画像画素アクセスポインタ
「int h;」は、水平幅
「int v;」は、垂直幅
「int inc_s;」は、S(元)画像の増加幅
「int inc_d;」は、D(結果)画像の増加幅

(D―2)アルゴリズムコード

    ptrs  = (UWORD*)ps->adr;                        // S配列実Ptr取出
    ptrd  = (double*)pd->adr;                       // D配列実Ptr取出
    h     = ps->h;                                  // 水平幅を取り出し
    v     = ps->v;                                  // 垂直幅を取り出し
    inc_s = ps->inc;                                // 増加幅:Sを取出
    inc_d = pd->inc;                                // 増加幅:Dを取出
    if( h == inc_s && h == inc_d ){                 // 水平幅=全増加幅の時
        convert_w_d_x( ptrs, ptrd, lut, h * v );    // 連続で LUT 変換
    }else{                                          // 異なる時
        while( --v >= 0 ){                          // 垂直方向に繰返し
            convert_w_d_x( ptrs, ptrd, lut, h );    // 水平方向 LUT 変換
            ptrs += inc_s;                          // 垂直方向増加S
            ptrd += inc_d;                          // 垂直方向増加D
        }                                           // 
    }                                               // 
}

「ptrs=(UWORD*)ps->adr;ptrd=(double*)pd->adr;」は、
SD両者の画像画素アクセスポインタを内部で使い易い様に
セット!
「h=ps->h;v=ps->v;」は、水平幅・垂直幅をセット
★備考★「ps->h」とS(元)画像のサイズを使用して居ま
す!この様に使う物と考えて仮引数をセットして居ます!
「inc_s=ps->inc;inc_d=pd->inc;」は、SDそれぞれの
増加幅をセット
「if(h==inc_s&&h==inc_d){
convert_w_d_x(ptrs,ptrd,lut,hv);}」は、if条件
「h==inc_s&&h==inc_d」と水平幅とSDそれぞれの増加幅
が等しい場合は、一次元配列同士の処理と考えられるので
「convert_w_d_x(ptrs,ptrd,lut,hv);」とサブルーチン
関数「convert_w_d_x()」で処理します!
「else{while(--v>=0){convert_w_d_x(ptrs,ptrd,lut,h);
ptrs+=inc_s;ptrd+=inc_d;}」は、「else」詰り、前述の
if条件が不成立時「水平幅とSDそれぞれの増加幅が異
なる」場合で二次元的に垂直方向処理をwhile構文で
行う必要が有るのでループ条件「--v>=0」と良く紹介する
ダウンカウン方式で高速化し、ループ中身
「convert_w_d_x(ptrs,ptrd,lut,h);ptrs+=inc_s;
ptrd+=inc_d;」とサブルーチン関数「convert_w_d_x()」で
水平方向のLUT変換処理を行い、「ptrs+=inc_s;
ptrd+=inc_d;」と垂直方向にポインタを移動と繰り返す
処理を行う事で画像を二次元として処理します!
★備考★典型的な二次元画像処理として垂直方向に水平方向
の処理を繰り返す方法でコノ形式のアルゴリズムは良く使用
しています!

(4-15-82)関数「int convert_w_d(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換:実行部:2バイト→LUT→倍精度                *****/
/************************************************************************/

int             CopyClear::convert_w_d(
    TypeArray   *ps,                                    // S配列
    TypeArray   *pd,                                    // D配列
    TypeArray   *lut                                    // LUT
){
    double      *buf;                                   // バッファー
    double      *plut;                                  // LUTへのPtr

    buf = (double*)malloc( sizeof(double) * 65536 );    // メモリ確保
    if( buf == 0 ){                                     // 失敗時
        return( STI_MEM );                              // 左記を返す
    }                                                   // 
    plut = MoveArrayDouble( lut, buf, 65536 );          // BufへCOPY
    if( plut == 0 ){                                    // 失敗時は、
        free( buf );                                    // メモリ解放し
        return( STI_ARY_5 - 20 );                       // 2番引数ERR
    }                                                   // 
    convert_w_d_y( ps, pd, plut );                      // LUT変換:2→4垂直
    free( buf );                                        // メモリ解放し
    return( END_STI );                                  // 正常終了 
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w_d();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
「_d」は、「double型」詰り、「double型」詰り倍精度
浮動小数点型単位を意味!
「_w_s」で「UWORD型」の画素から「double型」のLUTを使用して「double型」詰り倍精度浮動小数点型単位作成で
す!
★備考★サブルーチン関数「convert_w_d_y()」を使用して
処理する仮引数「TypeArray* lut」が「TypeArray*」に
成っているバージョンの関数です!

(B)関数「int convert_w_d();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w_d()」の【仮引数】

int             CopyClear::convert_w_d(
    TypeArray   *ps,                                    // S配列
    TypeArray   *pd,                                    // D配列
    TypeArray   *lut                                    // LUT
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w_d()」の【アルゴリズム】

){
    double      *buf;                                   // バッファー
    double      *plut;                                  // LUTへのPtr

    buf = (double*)malloc( sizeof(double) * 65536 );    // メモリ確保
    if( buf == 0 ){                                     // 失敗時
        return( STI_MEM );                              // 左記を返す
    }                                                   // 
    plut = MoveArrayDouble( lut, buf, 65536 );          // BufへCOPY
    if( plut == 0 ){                                    // 失敗時は、
        free( buf );                                    // メモリ解放し
        return( STI_ARY_5 - 20 );                       // 2番引数ERR
    }                                                   // 
    convert_w_d_y( ps, pd, plut );                      // LUT変換:2→4垂直
    free( buf );                                        // メモリ解放し
    return( END_STI );                                  // 正常終了 
}

(D-1)ローカル変数

){
    double      *buf;                                   // バッファー
    double      *plut;                                  // LUTへのPtr

「double* buf;」は、ローカルバッファー
「double* plut;」は、LUTへのポインタ

(D―2)アルゴリズムコード

    buf = (double*)malloc( sizeof(double) * 65536 );    // メモリ確保
    if( buf == 0 ){                                     // 失敗時
        return( STI_MEM );                              // 左記を返す
    }                                                   // 
    plut = MoveArrayDouble( lut, buf, 65536 );          // BufへCOPY
    if( plut == 0 ){                                    // 失敗時は、
        free( buf );                                    // メモリ解放し
        return( STI_ARY_5 - 20 );                       // 2番引数ERR
    }                                                   // 
    convert_w_d_y( ps, pd, plut );                      // LUT変換:2→4垂直
    free( buf );                                        // メモリ解放し
    return( END_STI );                                  // 正常終了 
}

「buf=(double*)malloc(sizeof(double)*65536);」は、
バッファーのメモリ動的確保!★備考★昔は65536
サイズの配列で確保する事がコンパイルシステムで許可出来
無かったシステムが多かったのです!
「if(buf==0){return(STI_MEM);}」は、確保失敗したら、
エラーコード「STI_MEM」を関数辺値とし返し関数終了!
「plut=MoveArrayDouble(lut,buf,65536);」は、バッファー
へLUTデータをコピー
「if(plut==0){free(buf);return(STI_ARY_5-20);}」は、
もし、エラー≪コピー出来無い時≫が有れば、後始末
「free(buf);」とし確保メモリ解放し、エラーコード
「STI_ARY_5-20」と「-20」で2番目の「TypeArray型」が
エラー位置を示すを関数辺値とし返し関数終了!
「convert_w_d_y(ps,pd,plut);」は、サブルーチン関数
「convert_w_d_y()」で二次元配列的に画像を処理!
「return(END_STI);」は、関数辺値とし正常終了を返し
関数終了!

(4-15-83)関数「int convert_w(
TypeArray* ps,
TypeArray* pd,TypeArray* lut){・・・}」

/************************************************************************/
/*****  LUT変換コマンド              :S=WORDの時          *****/
/*****  CONVERT,s,d[,LUT]                          *****/
/************************************************************************/

int             CopyClear::convert_w(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT配列
){
    switch( pd->w ){                                // Dの処理幅が
    case 1:                                         // 1バイト単位なら
        return( convert_w_b( ps, pd, lut ) );       // 左記でLUT変換
    case 2:                                         // 2バイト単位なら
        return( convert_w_s( ps, pd, lut ) );       // 左記でLUT変換
    case 4:                                         // 4バイト整数か
        return( convert_w_l( ps, pd, lut ) );       // 左記でLUT変換
    case 101:                                       // 単精度単位なら
        return( convert_w_f( ps, pd, lut ) );       // 左記でLUT変換
    case 102:                                       // 倍精度単位なら
        return( convert_w_d( ps, pd, lut ) );       // 左記でLUT変換
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 20 );                   // 不正を返す
    }                                               //
}

☆備考☆この関数はファイル「CopyClear030.cpp」に存在!
★注意★この関数は「private:属性」ですのでライブラリの
外から使用不能です!

(A)関数「convert_w();」の【関数名】

「convert」は、英単語「Convert」として変換するの意味で
す!
「_w」は、「UWORD型」詰り2バイト単位を意味!
★備考★S(元)画像が2バイト単位でのLUT変換
関数です!

(B)関数「int convert_w();」の【返値】

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!

(C)関数「convert_w()」の【仮引数】

int             CopyClear::convert_w(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd,                                // D配列
    TypeArray   *lut                                // LUT配列
){

「TypeArray* ps,」は、S(元)画像
「TypeArray* pd,」は、D(結果)画像
「TypeArray* lut」は、LUTルックアップテーブル

(D)関数「convert_w()」の【アルゴリズム】

){
    switch( pd->w ){                                // Dの処理幅が
    case 1:                                         // 1バイト単位なら
        return( convert_w_b( ps, pd, lut ) );       // 左記でLUT変換
    case 2:                                         // 2バイト単位なら
        return( convert_w_s( ps, pd, lut ) );       // 左記でLUT変換
    case 4:                                         // 4バイト整数か
        return( convert_w_l( ps, pd, lut ) );       // 左記でLUT変換
    case 101:                                       // 単精度単位なら
        return( convert_w_f( ps, pd, lut ) );       // 左記でLUT変換
    case 102:                                       // 倍精度単位なら
        return( convert_w_d( ps, pd, lut ) );       // 左記でLUT変換
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 20 );                   // 不正を返す
    }                                               //
}

概要「switch(pd->w){・・switch分岐本体・・}」で
D(結果)画像の画素単位が
「case 1:return(convert_w_b(ps,pd,lut));」と1バイト
整数型ならば、「return(convert_w_b(ps,pd,lut));」で
サブルーチン関数「convert_w_b()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 2:return(convert_w_s(ps,pd,lut));」と2バイト
整数型ならば、「return(convert_w_s(ps,pd,lut));」で
サブルーチン関数「convert_w_s()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 4:return(convert_w_l(ps,pd,lut));」と4バイト
整数型ならば、「return(convert_w_l(ps,pd,lut));」で
サブルーチン関数「convert_w_l()」で処理し、この関数の
関数辺値を関数辺値とし返し関数終了!
「case 101:return(convert_w_f(ps,pd,lut));」と単精度
浮動小数点型ならば「return(convert_w_f(ps,pd,lut));」
でサブルーチン関数「convert_w_f()」で処理し、この関数
の関数辺値を関数辺値とし返し関数終了!
「case 102:return(convert_w_d(ps,pd,lut));」と単精度
浮動小数点型ならば「return(convert_w_d(ps,pd,lut));」
でサブルーチン関数「convert_w_d()」で処理し、この関数
の関数辺値を関数辺値とし返し関数終了!
「default:return(STI_ARY_5-20);」は、画素単位を示す
値が対象外とし、エラーコード「STI_ARY_5-20」を返し
関数終了!

(E)関数「convert_w()」の【備考】

ここと関数「convert_b()」で記載した様にLUT変換の
関数のS(元)画像は、「BYTE型」(unsigned char型)
か「UWORD型」(unsigned short型)しか、存在しません!
想定したカメラが元々はアナログカメラをAD(アナログ
デジタル)変換するキャプチャー回路で8ビットに量子化
するか、デジタルカメラの多くが8ビットの画素サイズで
私が、21世紀に英国製「アンドリュー製のカメラで応用
として映像で無く分光光度計用のセンサーとし使用」した
時も10ビットの分解能≪0..1023の値≫が使えるカメラで
当然、理解して頂けていると思うけどカメラは、0以上の
値を発生する物としてライブラリ関数は設計していますの
で「(unsigned char型)・(unsigned short型)」を使用
しています!

ココまでで区切り≪「private:属性」の関数の並びが、
「convert_w()」関数までと大きく成り過ぎて
note編集が難しく成ったので≫が良いので
継続追加は有りません!★備考★
勿論、記載ミスは直して行きますが!
引き続き、
新規解説『解説クラスCopyClear(33)』
御贔屓下さい!

文末


いいなと思ったら応援しよう!