見出し画像

解説クラスCopyClear(10)

解説クラスCopyClear(10)


2024年3月14初講(初稿)

この講義は解説『解説クラスCopyClear(9)』
及びの解説『解説クラスCopyClear(9ダッシュ)
の続きです!
この「解説クラスCopyClear(10)」では、
「CopyClear.cpp」ファイルから始め「CopyClear000.cpp」
⇒「CopyClear010.cpp」⇒「CopyClear010.cpp」⇒
「CopyClear020.cpp」と枝番号の若いファイルから順に説明
して行きます!とする基本方針が良いと思ったのですが、
最初の「CopyClear.cpp」ファイル等は、都合で後回しとし、
実際に使用頻度の高い「CopyClear010.cpp」から順に解説を
行います!
更にファイルの頭から順に解説を行いません!直接、ライブ
ラリの関数が利用できる「public:属性」の関数から解説を
行います!「private:属性」の関数は、サブルーチン関数と
して「public:属性」の関数の下請けなので動作の
アルゴリズム解説の為に説明しますが直接「public:属性」
の関数を使用して頂く為に、この順番を採用しました!

(4-13)例文実行用の準備

解説文章『例文実行の手引き』に有る様に、
大域変数「FUN」を定義して準備とします!そして
BMP形式画像ファイルで実行結果が解る様にします!
OSが良く使われて居る物≪マイクロソフトウィンドウズや
アップルOS及びアンドロイドのスマホ≫でも画像ファイル
として観える筈です!詰り、読者様で使用出来るC++が
コンパイル&GOが出来る環境で作成したBMPファイルを
観る事が出来る筈です!

(4-14)関数の詳細解説

ここでは、「CLEAR系」=同じ画素値で画像メモリを埋
める動作を担う関数群です!

(4-14-1)関数「int Clear(
TypeArray* pa,int data){・・・}」の説明

int                 CopyClear::Clear(
    TypeArray       *pa,                                //  配列
    int             data                                //  データ
){
    if( pa == 0 ){                                      // 空なら
        return( STI_ARY_0 - 10 );                       // 左記を返す
    }else if( pa->adr == 0 ){                           // Adrが空なら
        return( STI_ARY_1 - 10 );                       // 左記を返す
    }                                                   // 
    switch( pa->w ){                                    // 単位が
    case 1:                                             // 1BYTE単位なら
        clear_1( pa, data );                            // 1BYTE単位クリア
        break;                                          // 
    case 2:                                             // 2BYTE単位なら
        clear_2( pa, data );                            // 2BYTE単位クリア
        break;                                          // 
    case 4:                                             // 4BYTE単位なら
        clear_4( pa, data );                            // 4BYTE単位クリア
        break;                                          // 
    case 101:                                           // 単精度単位か
    case 102:                                           // 倍精度単位なら
        return( Clear( pa, (double)data ) );            // 実数型クリア
    default:                                            // 上記以外なら
        return( STI_ARY_5 - 10 );                       // 1番配列不正を返す
    }                                                   //
    return( END_STI );                                  // 正常終了 
}

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

(4-14-1-A)関数「int Clear(・・・);」の
【関数名】説明

「Clear」は、英単語「Clear」で日本語訳「きれいになる、
片付く、消える」と有り、ここでは、綺麗に消す=画像を
消す⇒同じ画素の値で消す=指定した整数値で同じ値を書き
込むとしました!

(4-14-1-B)関数「int Clear(・・・);」の
【返値】説明

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

(4-14-1-C)関数「int Clear(・・・);」の
【仮引数】説明

int                 CopyClear::Clear(
    TypeArray       *pa,                                //  配列
    int             data                                //  データ
){

仮引数「TypeArray* pa,」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「TypeArray* 」を多くの画像処理関数の画像をコノ
形式で表します!
仮引数「int data」は、指定した画像「TypeArray* pa」の
全画素を同じ値で書き込む整数「int型」値です!
★注意★「C++言語仕様」としてのオーバーロード関数(
多重定義)として同じ関数名で他の型の仮引数も存在しま

(4-14-1-D)関数「int Clear(・・・);」の
【アルゴリズム】説明

){
    if( pa == 0 ){                                      // 空なら
        return( STI_ARY_0 - 10 );                       // 左記を返す
    }else if( pa->adr == 0 ){                           // Adrが空なら
        return( STI_ARY_1 - 10 );                       // 左記を返す
    }                                                   // 
    switch( pa->w ){                                    // 単位が
    case 1:                                             // 1BYTE単位なら
        clear_1( pa, data );                            // 1BYTE単位クリア
        break;                                          // 
    case 2:                                             // 2BYTE単位なら
        clear_2( pa, data );                            // 2BYTE単位クリア
        break;                                          // 
    case 4:                                             // 4BYTE単位なら
        clear_4( pa, data );                            // 4BYTE単位クリア
        break;                                          // 
    case 101:                                           // 単精度単位か
    case 102:                                           // 倍精度単位なら
        return( Clear( pa, (double)data ) );            // 実数型クリア
    default:                                            // 上記以外なら
        return( STI_ARY_5 - 10 );                       // 1番配列不正を返す
    }                                                   //
    return( END_STI );                                  // 正常終了 
}

「if(pa==0){return(STI_ARY_0-10);}else if(pa->adr==0){
return(STI_ARY_1-10);}」は、条件「if(pa==0)」で
仮引数「TypeArray* pa,」の値が0「空ポインタ」の場合
「return(STI_ARY_0-10);」とエラーコードを返します!
条件「if(pa->adr==0)」で仮引数「TypeArray* pa,」内の
メンバー変数「pa->adr」の値が0「空ポインタ」の場合
「return(STI_ARY_1-10);」とエラーコードを返します!
「switch(・・値・・){・・分岐本体・・}」と
switch構文ブロックで値「pa->w」と
仮引数「TypeArray* pa,」内のメンバー変数「pa->w」の
値で「caseタグ」の所に分岐(ジャンプ)し、
タグ「case1:」で「clear_1(pa,data);break;」と
サブルーチンの関数「clear_1(pa,data);」で処理し、
「break;」構文でswitch構文ブロックから抜けます!
タグ「case2:」で「clear_2(pa,data);break;」と
サブルーチンの関数「clear_2(pa,data);」で処理し、
「break;」構文でswitch構文ブロックから抜けます!
タグ「case4:」で「clear_4(pa,data);break;」と
サブルーチンの関数「clear_4(pa,data);」で処理し、
「break;」構文でswitch構文ブロックから抜けます!
タグ「case101:」及びタグ「case102:」で同じ名称
関数(オーバーロード多重定義関数)
「Clear(pa,(double)data)」で処理し、
「break;」構文でswitch構文ブロックから抜けます!
メンバー変数「pa->w」の値が全ての「caseタグ」に
一致しない場合「default:」構文の所、詰り
「return(STI_ARY_5-10);」とエラーコード
「STI_ARY_5-10」を返し関数終了!

(4-14-1-E)関数「int Clear(・・・);」の
【使用例】説明

#include"ImageFunc.h"           // 画像処理ライブラリ用
ImageFunc FUN;                  // ライブラリ関数使用定義

main()
{
    TypeArray   img;            // 画像型変数
    TypeArray*  pimg=&img;      // 上記へのポインタ

    pimg->MallocBYTE (640,480); // 640×480画像メモリ取得
    FUN.Clear(pimg,0);          // 画像メモリ「0クリア」
//作成した画像をBMP形式ファイルとして作成
    FUN.WriteBitmap("testFile1.bmp",pimg);

    FUN.Clear(pimg,255);        // 画像メモリ「画素を
                                // 数値255クリア
                                // ⇒8ビット画像で最明」にする!
    //作成した画像をBMP形式ファイルとして作成
    FUN.WriteBitmap("testFile2.bmp",pimg);
    pimg->freeMem();//画像メモリ解放
}

初回の例文なので「#include・・・main(){・・中身・・}」
も記載しましたが、C言語/C++言語をご存じの方への
画像処理ライブラリ解説なので次回からは、
「{・・中身・・}」と中身だけ記載します!
まず、今回の解説、
「TypeArray img;」で画像型変数を定義
「TypeArray* pimg=&img;」で上記をポインタとして
使用した事を示します★注意★多くの画像処理関数では、
このポインタの形を仮引数として使用します!★
「pimg->MallocBYTE (640,480);」でサイズ640×480
の画像メモリをシステムから実体として取得する事を示し
ます!
「FUN.Clear(pimg,0);」で今回、説明した「Clear()」関数
で0クリアした事を示します!★注意★「FUN.Clear」と
C++言語に馴染んで居る方には、ご存じの記載ですが、
C言語しか使用されて無い方に解説「クラスImageFuncと
画像処理ライブラリを駆動するクラスを型として定義した
変数FUNのメンバー関数(メソッド)として
【Clear(pimg,0);】と関数の機能を実行する事を意味
します」のでこの記述で動作します!
「FUN.WriteBitmap("testFile1.bmp",pimg);」で
BMP形式のファイルフォーマットでファイル名
「testFile1.bmp」と画像「pimg」のファイルを生成し書き
込みます!
「FUN.Clear(pimg,255);」で画素値255(8ビット画像
では最高値=最も明るい)で全ての画像を埋め込む処理!
「FUN.WriteBitmap("testFile2.bmp",pimg);」で
BMP形式のファイルフォーマットでファイル名
「testFile2.bmp」と画像「pimg」のファイルを生成し書き
込みます!

testFile1

★注意★画像ファイル「testFile1.bmp」のイメージを表現
して見ましたが、「Note」背景表示を黒色にして居る
読者様には、隙間が空いているだけと見えるカモしれません

testFile2

★注意★画像ファイル「testFile2.bmp」のイメージを表現
して見ましたが、「Note」背景表示を白色にして居る
読者様には、隙間が空いているだけと見えるカモしれません

多分、真面に読んで頂いて居る人は、説明して無かった事が
有ると思ったでしょう!「pimg->MallocBYTE ();」も、解説
「クラスTypeArrayと画像メモリ定義用の型として使用
したポインタpimgから【pimg->MallocBYTE ()】とメソッド
を実行する事は理解して頂いて居ると思います!」
そして最後に「pimg->freeMem();」で取得した
画像メモリをシステムに返してから終わる事がマナーです!
★注意&警告★マナーと言う依りも必須ですから!!

(4-14-2)関数「int Clear(
TypeArray* pa,double data){・・・}」の説明

int             CopyClear::Clear(
    TypeArray   *pa,                                //  配列
    double      data                                //  データ
){
    switch( pa->w ){                                // 単位が
    case 101:                                       // 単精度単位なら
        clear_float( pa, data );                    // 単精度単位クリア
        break;                                      // 
    case 102:                                       // 倍精度単位なら
        clear_double( pa, data );                   // 倍精度単位クリア
        break;                                      // 
    case 1:                                         // 1BYTE単位なら
    case 2:                                         // 2BYTE単位なら
    case 4:                                         // 4BYTE単位なら
        return( Clear( pa, (int)data ) );           // 整数型でクリア
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 10 );                   // 1番配列不正を返す
    }                                               //
    return( END_STI );                              // 正常終了 
}

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

(4-14-2-A)関数「int
Clear(・・・)」の【関数名】説明

「Clear」は、英単語「Clear」で日本語訳「きれいになる、
片付く、消える」と有り、ここでは、綺麗に消す=画像を
消す⇒同じ画素の値で消す=指定した浮動小数点数値で同
じ値を書き込むとしました!

(4-14-2-B)関数「int
Clear(・・・)」の【返値】説明

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

(4-14-2-C)関数「int
Clear(・・・)」の【仮引数】説明

int             CopyClear::Clear(
    TypeArray   *pa,                                //  配列
    double      data                                //  データ
){

仮引数「TypeArray* pa,」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「TypeArray* 」を多くの画像処理関数の画像をコノ
形式で表します!
仮引数「double data」は、指定した
画像「TypeArray* pa」の全画素を同じ値で書き込む
浮動小数点数値「double型」の値です!
★注意★「C++言語仕様」としてのオーバーロード関数(
多重定義)として同じ関数名で他の型の仮引数も存在します

(4-14-2-D)関数「int
Clear(・・・)」の【アルゴリズム】説明

){
    switch( pa->w ){                                // 単位が
    case 101:                                       // 単精度単位なら
        clear_float( pa, data );                    // 単精度単位クリア
        break;                                      // 
    case 102:                                       // 倍精度単位なら
        clear_double( pa, data );                   // 倍精度単位クリア
        break;                                      // 
    case 1:                                         // 1BYTE単位なら
    case 2:                                         // 2BYTE単位なら
    case 4:                                         // 4BYTE単位なら
        return( Clear( pa, (int)data ) );           // 整数型でクリア
    default:                                        // 上記以外なら
        return( STI_ARY_5 - 10 );                   // 1番配列不正を返す
    }                                               //
    return( END_STI );                              // 正常終了 
}

「switch(・・値・・){・・分岐本体・・}」と
switch構文ブロックで値「pa->w」と
仮引数「TypeArray* pa,」内のメンバー変数「pa->w」の
値で「caseタグ」の所に分岐(ジャンプ)し、
タグ「case101:」で「clear_float(pa,data);
break;」とサブルーチンの関数
「clear_float(pa,data);」で処理し、「break;」構文で
switch構文ブロックから抜けます!
タグ「case102:」で「clear_double(pa,data);
break;」とサブルーチンの関数
「clear_double(pa,data);」で処理し、「break;」構文で
switch構文ブロックから抜けます!
タグ「case1:」・「case2:」・「case4:」で
「return(Clear(pa,(int )data));」とオーバーロード多重
定義関数をサブルーチンとし処理し関数終了!
メンバー変数「pa->w」の値が全ての「caseタグ」に
一致しない場合「default:」構文の所、詰り
「return(STI_ARY_5-10);」とエラーコード
「STI_ARY_5-10」を返し関数終了!
★注意★同じ名称のオーバーロード関数
「int Clear(TypeArray* pa,int data)」と異なり
仮引数「TypeArray* pa,」のポインタ自体の検査を行って
いません!★備考★元々サブルーチンとして作成し、検査を
省き多少、速度アップを考えたからで注意して使用して下さ
い!

(4-14-2-E)関数「int
Clear(・・・)」の【使用例】説明

{
    TypeArray   img;                // 画像型変数
    TypeArray*  pimg = &img;        // 上記へのポインタ
    TypeArray   Wimg;               // 画像型変数
                                    //:フィル書き込み用
    TypeArray*  pWimg = &Wimg;      // 上記へのポインタ

    pimg->MallocFloat( 640, 480 );  // 640×480画像メモリ取得
    FUN.Clear( pimg, 0.0 );         // 画像メモリ「0クリア」
    pWimg->MallocBYTE( 640, 480 );  // 640×480画像メモリ取得

    FUN.Clear( pimg, 123.456 );     // 画像メモリ「画素を
                                    // 数値123.456クリア
    FUN.Copy( pimg, pWimg );        // フィル書き込み用へコピー
//作成した画像をBMP形式ファイルとして作成
    FUN.WriteBitmap( "testFile3.bmp", pWimg );

    pimg->freeMem();                // 画像メモリ解放
    pWimg->freeMem();               // 画像メモリ解放
}

「{・・中身・・}」と中身だけ記載します!
まず、今回の解説、
「TypeArray img;」で画像型変数を定義
「TypeArray* pimg=&img;」で上記をポインタとして
使用した事を示します★注意★多くの画像処理関数では、
このポインタの形を仮引数として使用します!★
「pimg->MallocFloat(640,480);」でサイズ640×480
の単精度浮動小数点型画素画像メモリをシステムから
実体として取得する事を示します!
「FUN.Clear(pimg,123.456);」で今回、説明した
「Clear()」関数で浮動小数点数値「123.456」でクリア
した事を示します!
「pWimg->MallocBYTE (640,480);」で
サイズ640×480の1バイト単位画素画像メモリを
システムから実体として取得する事を示します!
「FUN.Copy(pimg,pWimg);」で単精度浮動小数点数値画素
の画像から1バイト単位画像へコピー≪値は、小数点以下を
切り捨て≫する事を示します!
「FUN.WriteBitmap("testFile3.bmp",pimg);」で
BMP形式のファイルフォーマットでファイル名
「testFile3.bmp」と画像「pimg」のファイルを生成し書き
込みます!
★注意★「FUN.Clear」とC++言語に馴染んで居る方には
ご存じの記載ですが、C言語しか使用されて無い方に
解説「クラスImageFuncと画像処理ライブラリを駆動する
クラスを型として定義した変数FUNのメンバー関数(
メソッド)として【Clear(pimg,0);】と関数の機能を
実行する事を意味します」のでこの記述で動作します!
「FUN.Clear(pimg,123.456);」で画素値123.456(
浮動小数点数値なので小数点以下も書き込み可能)で
全ての画像を埋め込む処理!

testFile3

★注意★画像ファイル「testFile3.bmp」のイメージを表現
して見ましたが、「Note」背景表示を同じ濃淡灰色にし
て居る読者様には、隙間が空いているだけと見えるカモしれ
ませんが、変な背景表示なので多分居ない筈!
多分、真面に読んで頂いて居る人は、説明して無かった事が
有ると思ったでしょう!「pimg->MallocFloat();」も、
解説「クラスTypeArrayと画像メモリ定義用の型として使用
したポインタpimgから【pimg->MallocFloat()】とメソッド
を実行する事は理解して頂いて居ると思います!」
そして最後に「pimg->freeMem();」と
「pWimg->freeMem();」で取得した画像メモリを
システムに返してから終わる事がマナーです!
★注意&警告★マナーと言う依りも必須ですから!!

(4-14-3)関数「int Copy(
TypeArray* ps,TypeArray* pd);{・・・}」の説明

int             CopyClear::Copy(
    TypeArray   *ps,                                // S配列
    TypeArray   *pd                                 // D配列
){
    TypeArray   s;                                  // S:サイズ補正後
    TypeArray   d;                                  // D:サイズ補正後
    int         ws;                                 // S配列の単位幅
    int         wd;                                 // D配列の単位幅
    int         hv;                                 // 水平/垂直幅

    s     = *ps;                                    // S配列を補正する
    ps    = &s;                                     // ため情報をコピー
    d     = *pd;                                    // D配列を補正する
    pd    = &d;                                     // ため情報をコピー
    hv    = ( ps->h < pd->h ) ? ps->h : pd->h;      // 水平幅を最小で
    ps->h = hv;                                     // 補正
    pd->h = hv;                                     // 
    hv    = ( ps->v < pd->v ) ? ps->v : pd->v;      // 垂直幅を最小で
    ps->v = hv;                                     // 補正
    pd->v = hv;                                     // 
    ws    = ps->w;                                  // 単位幅取出し:S
    wd    = pd->w;                                  // 単位幅取出し:D
    if( ws == wd ){                                 // 同一単位なら
        return( copy_even( ps, pd ) );              // 左記でコピー
    }else{                                          // 上記以外なら
        return( copy_diff( ps, pd ) );              // 左記でコピー
    }                                               // 
}

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

(4-14-3-A)関数「int Copy(・・・)」の
【関数名】説明

「Copy」は、英単語「Copy」で日本語のカタカナ語「
コピーする」と普通に使用して居る単語です、ここでは、
画像を「S(ソース)⇒D(デスティネーション)」と
画像メモリ間でコピーします!
★注意★S⇒Dで画素の型が異なる場合は型変換が起こり
ます!

(4-14-3-B)関数「int Copy(・・・)」の
【返値】説明

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

(4-14-3-C)関数「int Copy(・・・)」の
【仮引数】説明

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

仮引数「TypeArray* ps,」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「TypeArray* 」を多くの画像処理関数の画像をコノ
形式で表します!そして「s」は、ソース=元の画像を示し
仮引数「TypeArray* pd」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「二項演算」的にを多くの画像処理関数の「d」詰り
デスティネーション画像を示し、「S⇒D」と元(s)が
先で結果側(d)が後でとの順番で記載する関数が多い事も
表します!

(4-14-3-D)関数「int Copy(・・・)」の
【ローカル変数】説明

){
    TypeArray   s;                                  // S:サイズ補正後
    TypeArray   d;                                  // D:サイズ補正後
    int         ws;                                 // S配列の単位幅
    int         wd;                                 // D配列の単位幅
    int         hv;                                 // 水平/垂直幅

「TypeArray s;」で内部で使用するS(元)画像の
ローカルな画像情報★注意★オリジナルを変更シナイ★
「TypeArray s;」で内部で使用するS(元)画像の
ローカルな画像情報★注意★オリジナルを変更シナイ★
「int ws;」は、S画像の単位幅を使い易くした変数
「int wd;」は、D画像の単位幅を使い易くした変数
「int hv;」は、画像の水平幅/垂直幅を使い易くした変数
★備考★上記のコードのコメント(//右側)に「配列」と
有るのは、元々ハードウェアで画像メモリを高速に処理する
ADS社画像処理装置用に作成されたプログラムが元で配列
とは、CPUで処理する画像メモリと区別していた名残です

(4-14-3-E)関数「int Copy(・・・)」の
【アルゴリズム】説明

    s     = *ps;                                    // S配列を補正する
    ps    = &s;                                     // ため情報をコピー
    d     = *pd;                                    // D配列を補正する
    pd    = &d;                                     // ため情報をコピー
    hv    = ( ps->h < pd->h ) ? ps->h : pd->h;      // 水平幅を最小で
    ps->h = hv;                                     // 補正
    pd->h = hv;                                     // 
    hv    = ( ps->v < pd->v ) ? ps->v : pd->v;      // 垂直幅を最小で
    ps->v = hv;                                     // 補正
    pd->v = hv;                                     // 
    ws    = ps->w;                                  // 単位幅取出し:S
    wd    = pd->w;                                  // 単位幅取出し:D
    if( ws == wd ){                                 // 同一単位なら
        return( copy_even( ps, pd ) );              // 左記でコピー
    }else{                                          // 上記以外なら
        return( copy_diff( ps, pd ) );              // 左記でコピー
    }                                               // 
}

「s=*ps;ps=&s;」は、S(ソース=元)画像の画像情報を
ローカル変数「s」に移し、「&s」とポインタの値をロー
カル変数に置き換え!
「d=*pd;pd=&d;」は、D(デスティネーション=結果)
画像の画像情報をローカル変数「d」に移し、「&d」と
ポインタの値をローカル変数に置き換え!
「hv=(ps->h<pd->h)?ps->h:pd->h;」は、SD両画像の
水平幅の最小値を算出、詰り、サイズが異なる場合の調整用
です!
「ps->h=hv;pd->h=hv;」は、上記で算出した最小水平幅で
SD両画像の水平幅を調整!
「hv=(ps->v<pd->v)?ps->v:pd->v;」は、SD両画像の
垂直幅の最小値を算出、詰り、サイズが異なる場合の調整用
です!
「ps->v=hv;pd->v=hv;」は、上記で算出した最小垂直幅で
SD両画像の垂直幅を調整!
「ws=ps->w;wd=pd->w;」は、ローカル変数に画像の
画素単位を扱い易い変数≪少しでも高速化の意味もある≫
「if(ws==wd){return(copy_even(ps,pd));}else{
return(copy_diff(ps,pd));}」は、
条件「if(ws==wd)」でSD両画像が同じ画素単位の場合
中身「return(copy_even(ps,pd));」で処理し関数終了!
条件非成立「}else{」で
中身「return(copy_diff(ps,pd));」で処理し関数終了!

(4-14-3-F)関数「int Copy(・・・)」の
【使用例】説明

{
    TypeArray   Rimg;               // 画像型変数
                                    // :フィル読み出し用
    TypeArray* pRimg=&Rimg;         // 上記へのポインタ
    TypeArray Wimg;                 // 画像型変数
//:フィル書き込み用
    TypeArray* pWimg=&Wimg;         // 上記へのポインタ
    TypeArray img;                  // 画像型変数
//:部分画像用
    TypeArray*  pimg=&img;          // 上記へのポインタ
    int         h;                  // 水平幅
    int         v;                  // 垂直幅
    int         c;                  // ビット幅
    long        xPixPerMeter;       // 今回は情報として
    long        xPiyPerMeter;       // 使用シナイ
    int         sti;                // ステータス情報

    sti=ReadBitmapAttribute(        	// ファイル情報読み出し
        "OrgFile.bmp",              	// ファイル「OrgFile.bmp」情報を読み出し
        &h, &v, &c,                 	// 今回、必要な情報格納変数
        &xPixPerMeter,              	// 今回、不要な情報だが、引数とし
        &yPixPerMeter);             	// てダミー使用
    if( sti != END_STI || c!=8 ){   	// 上記関数が実行時にエラー発生なら
        return;                     	// 例文を強制終了★注意★
    }                               	// 8ビット白黒画像が対象画像ファイル

    pRimg->MallocBYTE( h, v );      	// 水平幅×垂直幅画像メモリ取得
    FUN.Clear( pRimg, 0 );              // 画像メモリ「0クリア」
    ReadBitmap( "OrgFile.bmp",      	// ファイル「OrgFile.bmp」を読み出し
                        pRimg);     	//

	pWimg->MallocBYTE(					// 水平幅×倍×垂直幅×倍画像メモリ取得
	h * 2 + 1, v * 2 + 1 );				// 「+1」の部分は、隙間のサイズです
	FUN.Clear( pWimg, 0 );				// 画像メモリ「0クリア」

	pimg->subset( pWimg, 0, 0, h, v );	// 部分画像「左上」割り当て
	FUN.Copy( pRimg, pimg );			// 部分画像「左上」へ読み出し画像コピー

	pimg->subset( pWimg, h+1, 0, h, v );// 部分画像「右上」割り当て
	FUN.Copy( pRimg, pimg );			// 部分画像「右上」へ読み出し画像コピー

	pimg->subset( pWimg, 0, v+1, h, v );// 部分画像「左下」割り当て
	FUN.Copy( pRimg, pimg );			// 部分画像「左下」へ読み出し画像コピー

	pimg->subset( pWimg, h+1, v+1,		// 部分画像「右下」割り当て
							h, v );		//
	FUN.Copy( pRimg, pimg );			// 部分画像「右下」へ読み出し画像コピー

//作成した画像をBMP形式ファイルとして作成
	FUN.WriteBitmap("testFile4.bmp",pWimg);

	pRimg->freeMem();					//画像メモリ解放
	pWimg->freeMem();					//画像メモリ解放
}

今回の使用例で補助に使用したライブラリ関数

int ReadBitmapAttribute(//BMP属性読出
char*fname,//ファイル名
int &h,//水平幅
int &v,//垂直幅
int &c,//Bit幅(1,4,8,16,24,32)
long &xPixPerMeter,//水平解像度(Pix/m)
long &yPixPerMeter);//垂直解像度(Pix/m)

上記は、BMP形式画像ファイルの属性≪縦横のサイズを
コノ画像処理ライブラリの水平幅・垂直幅と必要な情報≫を
取得する関数です!ファイル名「char*fname」で指定
「int &h,int &v,int &c,」で諸情報をゲット出来ます!
上記は、BMP形式ファイルを読み出して画像メモリに
書き込む関数です!
今回の使用例≪BMP形式ファイルから画像メモリを読み
出し、それを縦横4枚並べた画像を今回の「Copy」で
作成し、BMP形式ファイルに大きな画像ファイルとして
書き込む≫

    pRimg->MallocBYTE( h, v );          // 水平幅×垂直幅画像メモリ取得
    FUN.Clear( pRimg, 0 );              // 画像メモリ「0クリア」
    ReadBitmap( "OrgFile.bmp",          // ファイル「OrgFile.bmp」を読み出し
                        pRimg);         //

上記は、BMP形式ファイルを読み出して画像メモリに
書き込む関数です!
「pRimg->MallocBYTE(h,v);」で読み出し用の画像メモリを
用意し、「FUN.Clear(pRimg,0);」で画像メモリを初期化
「ReadBitmap("OrgFile.bmp",pRimg);」で
ファイル「"OrgFile.bmp"」の画像(★注意★本当は8ビッ
ト白黒)を画像メモリに読み出す!

OrgFile.bmp

サンプルとして、この2024年4月にAKB48から卒業
する柏木由紀の一番輝いていた時期のアンアン表紙≪「かわ
いい」はもう卒業。みにつけたいのは、女の色気≫を光学
カメラ撮影≪ネットから盗ると罪が大きいが金を出して購入
した雑誌なのでと著作権法的に言い訳≫した写真を例として
使用しました!本当は、モノクロ(白黒濃淡)画像に使用
画像は成るのですが、折角、可愛い柏木由紀が白黒にすると
映え無いのでカラー画像を表示させました!これを8ビット
画素モノクロ表現に成るのですが、私がド貧乏人に成り、
動作するコンパイル環境が資金不足で無いので是非、解説『
投げ銭方式ライブラリのダウンロード』
で有料部分まで読ん
で私に正規の動作環境を恵んで下さい!
★注意★
上記例文で注意して欲しいのは、部分画像「pimg」には
「->freeMem()」で画像メモリを解放シナイ事です!
お判りと思いますが、「pimg->subset(pWimg,0,0,h,v);」
と「pWimg」の部分画像なのでメモリ取得は「pWimg」で
行い!部分画像「pimg」は、メモリ取得を行ってイナイので
取得して無いメモリを開放するとシステムが変に成る事を
考えて欲しい?!

    pWimg->MallocBYTE(                  // 水平幅×倍×垂直幅×倍画像メモリ取得
    h * 2 + 1, v * 2 + 1 );             // 「+1」の部分は、隙間のサイズです
    FUN.Clear( pWimg, 0 );              // 画像メモリ「0クリア」

ここでは、結果画像メモリを取得します!オリジナル画像に
対して縦横に倍+1画素≪1画像と言うのは隙間を開ける
部分です!≫

    pimg->subset( pWimg, 0, 0, h, v );  // 部分画像「左上」割り当て
    FUN.Copy( pRimg, pimg );            // 部分画像「左上」へ読み出し画像コピー

ここでは、結果画像の部分画像「左上」に対して元の画像を
「FUN.Copy(pRimg,pimg);」でコピーした事を示します!

    pimg->subset( pWimg, h+1, 0, h, v );// 部分画像「右上」割り当て
    FUN.Copy( pRimg, pimg );            // 部分画像「右上」へ読み出し画像コピー
    pimg->subset( pWimg, 0, v+1, h, v );// 部分画像「左下」割り当て
    FUN.Copy( pRimg, pimg );            // 部分画像「左下」へ読み出し画像コピー
    pimg->subset( pWimg, h+1, v+1,      // 部分画像「右下」割り当て
                            h, v );     //
    FUN.Copy( pRimg, pimg );            // 部分画像「右下」へ読み出し画像コピー

そして同じ様に「右上」・「左下」・「右下」とコピーした
事を意味!

//作成した画像をBMP形式ファイルとして作成
    FUN.WriteBitmap("testFile4.bmp",pWimg);
testFile4

「FUN.WriteBitmap("testFile4.bmp",pWimg);」でファイル
「"testFile4.bmp"」に書き込んだ事を画像で表示!
本当は、モノクロ(白黒濃淡)画像に使用画像は成るのです
が、折角、可愛い柏木由紀が白黒にすると映え無いので
カラー画像を表示させました!これを8ビット画素モノクロ
表現に成るのですが、私がド貧乏人に成り、動作する
コンパイル環境が資金不足で無いので是非、解説『投げ銭方
式ライブラリのダウンロード』
で有料部分まで読んで私に
正規の動作環境を恵んで下さい!
今回、クラス「CopyClear」の詳細説名を行うので
クラス名にも成って居る「Clear」・「Copy」の
両関数の詳細説明から始めました!
新しい項目なので受講者には、直ぐに理解は難しいと考え
ココまでとします!
近々、この解説文章に追記の方法で続きを記載し続講します
ので宜しく御贔屓お願いします!

2024年3月15追記

(4-14-4)関数「int CopyUnsignedShortInt(
TypeArray* ps,TypeArray* pd){・・・}」の説明

int             CopyClear::CopyUnsignedShortInt(
    TypeArray   *ps,                                    // S配列
    TypeArray   *pd                                     // D配列
){
    UWORD       *ptrs;                                  // 実Ptr:S配列
    long        *ptrd;                                  // 実Ptr:D配列
    int         h;                                      // 水平幅
    int         v;                                      // 垂直幅
    int         inc_s;                                  // 増加幅:S配列
    int         inc_d;                                  // 増加幅:D配列
    int         sti;                                    // ステータス情報

    sti = CheckImageInteger( ps, 2, 2 );                // S配列が2BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 10 );                             // 左記を返す
    }                                                   // 
    sti = CheckImageInteger( pd, 4, 4 );                // S配列が4BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 20 );                             // 左記を返す
    }                                                   // 
    ptrs  = (UWORD*)ps->adr;                            // SD配列の実Ptr
    ptrd  = (long*)pd->adr;                             // をセット
    h     = ( ps->h <= pd->h ) ? ps->h : pd->h;         // 水平幅最小を算出
    v     = ( ps->v <= pd->v ) ? ps->v : pd->v;         // 垂直幅最小を算出
    inc_s = ps->inc;                                    // 増加幅:Sを取出す
    inc_d = pd->inc;                                    // 増加幅:Dを取出す
    for( ; --v >= 0; ptrs += inc_s, ptrd += inc_d ){    // 垂直方向繰返し
        up_movu2l( ptrs, ptrd, h );                     // 水平方向に繰返す
    }                                                   // 
    return( END_STI );                                  // 正常終了 
}

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

(4-14-4-A)関数「int CopyUnsignedShortInt(
・・・」の【関数名】説明

「Copy」は、カタカナ語「コピー」意味通りコピーするです
「Unsignedshort 」は、画素画像が「unsignedshort 」と
符号無し2バイト(16ビット)整数の型を意味し、
「int 」は、画素画像が「int 」と符号有り4バイト(
32ビット)整数の型を意味し、整数型通しの型変換用の
関数を意味します!

(4-14-4-B)関数「int CopyUnsignedShortInt(
・・・」の【返値】説明

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

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!
ここでは、仮引数「TypeArray* ps,」がエラー発生なら
「return(sti-10);」と最初の画像引数がエラー、
仮引数「TypeArray* pd」がエラー発生なら
「return(sti-20);」と2番目の画像引数がエラーを
示します!

(4-14-4-C)関数「int CopyUnsignedShortInt(
・・・」の【仮引数】説明

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

仮引数「TypeArray* ps,」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「TypeArray* 」を多くの画像処理関数の画像をコノ
形式で表します!そして「s」は、ソース=元の画像を示し
仮引数「TypeArray* pd」は、画像(2次元配列)を示す
型「TypeArray」へのポインタ変数として、このライブラリ
では、「二項演算」的にを多くの画像処理関数の「d」詰り
デスティネーション画像を示し、「S⇒D」と元(s)が
先で結果側(d)が後でとの順番で記載する関数が多い事も
表します!

(4-14-4-D)関数「int CopyUnsignedShortInt(
・・・」の【アルゴリズム】説明

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

    sti = CheckImageInteger( ps, 2, 2 );                // S配列が2BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 10 );                             // 左記を返す
    }                                                   // 
    sti = CheckImageInteger( pd, 4, 4 );                // S配列が4BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 20 );                             // 左記を返す
    }                                                   // 
    ptrs  = (UWORD*)ps->adr;                            // SD配列の実Ptr
    ptrd  = (long*)pd->adr;                             // をセット
    h     = ( ps->h <= pd->h ) ? ps->h : pd->h;         // 水平幅最小を算出
    v     = ( ps->v <= pd->v ) ? ps->v : pd->v;         // 垂直幅最小を算出
    inc_s = ps->inc;                                    // 増加幅:Sを取出す
    inc_d = pd->inc;                                    // 増加幅:Dを取出す
    for( ; --v >= 0; ptrs += inc_s, ptrd += inc_d ){    // 垂直方向繰返し
        up_movu2l( ptrs, ptrd, h );                     // 水平方向に繰返す
    }                                                   // 
    return( END_STI );                                  // 正常終了 
}

ローカル変数

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

「UWORD* ptrs;」は、S画像の実ポインタ「型はUWORDと
unsigned short へのポインタ」とは理解して頂いて居ます
ね!
「long *ptrd;」は、D画像の実ポインタ「型はlong と
4バイト符号付き整数へのポインタ」とは理解して頂い
て居ますね!「int h;」は、実際にコピーする水平幅
「int v;」は、実際にコピーする垂直幅
「int inc_s;」は、S画像の増加幅
「int inc_d;」は、D画像の増加幅
「int sti;」は、ステータス情報(エラーコード)

アルゴリズムコード

    sti = CheckImageInteger( ps, 2, 2 );                // S配列が2BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 10 );                             // 左記を返す
    }                                                   // 
    sti = CheckImageInteger( pd, 4, 4 );                // S配列が4BYTEか検査
    if( sti != END_STI ){                               // 検査落ちならば
        return( sti - 20 );                             // 左記を返す
    }                                                   // 
    ptrs  = (UWORD*)ps->adr;                            // SD配列の実Ptr
    ptrd  = (long*)pd->adr;                             // をセット
    h     = ( ps->h <= pd->h ) ? ps->h : pd->h;         // 水平幅最小を算出
    v     = ( ps->v <= pd->v ) ? ps->v : pd->v;         // 垂直幅最小を算出
    inc_s = ps->inc;                                    // 増加幅:Sを取出す
    inc_d = pd->inc;                                    // 増加幅:Dを取出す
    for( ; --v >= 0; ptrs += inc_s, ptrd += inc_d ){    // 垂直方向繰返し
        up_movu2l( ptrs, ptrd, h );                     // 水平方向に繰返す
    }                                                   // 
    return( END_STI );                                  // 正常終了 
}

「sti=CheckImageInteger(ps,2,2);」は、S画像の情報の
検査で検査結果がローカル変数「sti」に格納!
「if(sti!=END_STI){return(sti-10);}」は、正常で
無いと判定ならば、「-10」と1番目の画像引数を示す
値を付けて関数終了!
「sti=CheckImageInteger(pd,4,4);」は、D画像の情報の
検査で検査結果がローカル変数「sti」に格納!
「if(sti!=END_STI){return(sti-20);}」は、正常で
無いと判定ならば、「-20」と2番目の画像引数を示す
値を付けて関数終了!
「ptrs=(UWORD)ps->adr;」は、S画像の先頭ポインタ
を取り出す!
「ptrd=(long *)pd->adr;」は、D画像の先頭ポインタを
取り出す!
「h=(ps->h<=pd->h)?ps->h:pd->h;」は、SD両画像の
水平幅最小値を実際にコピーする水平幅に算出!
「v=(ps->v<=pd->v)?ps->v:pd->v;」は、SD両画像の
垂直幅最小値を実際にコピーする垂直幅に算出!
「inc_s=ps->inc;」は、S画像の増加幅取り出し!
「inc_d=pd->inc;」は、D画像の増加幅取り出し!
「for(・・for中身・・){・・繰り返し中身・・}」は、
「(;--v>=0;ptrs+=inc_s,ptrd+=inc_d)」でループ前の
初期化「;」と何もしません!
判定「--v>=0;」とC言語前置カウントダウン演算子で
垂直幅分繰り返します!
ループ後処理「ptrs+=inc_s,ptrd+=inc_d」で
SD両画像の実ポインタをSDそれぞれの増加幅分
垂直方向に増加させる事を示します!
繰り返し中身「up_movu2l(ptrs,ptrd,h);」は、
垂直方向にfor構文で繰り返しているのでココでは、
サポートクラス「解説クラスSupport続き」で
説明した関数「up_movu2l()」を使用して
水平方向に1ライン処理します!
「return(END_STI);」は、関数が正常に実行された事を
示す値を返します!

(4-14-5)関数「int CopyFieldFrame(
TypeArray* ps,TypeArray* pd){・・・}」の説明

int             CopyClear::CopyFieldFrame(
    TypeArray   *ps,                                            // S配列
    TypeArray   *pd                                             // D配列
){
    TypeArray   s;                                              // S:サイズ補正後
    TypeArray   d;                                              // D:サイズ補正後
    int         h;                                              // 水平幅
    int         v;                                              // 垂直幅

    if( ps->w != 1 || pd->w != 1 ){                             // 8ビット画像以外ならば
        return( STI_ARY_5 );                                    // 不正を返す
    }                                                           // 
    s     = *ps;                                                // S配列を補正する
    ps    = &s;                                                 // ため情報をコピー
    d     = *pd;                                                // D配列を補正する
    pd    = &d;                                                 // ため情報をコピー
    h     = ( ps->h < pd->h ) ? ps->h : pd->h;                  // 水平幅を最小で
    ps->h = h;                                                  // 補正
    pd->h = h;                                                  // 
    v     = ps->v * 2;                                          // S画像の垂直幅×2
    v     = ( v < pd->v ) ? v : pd->v;                          // 垂直幅を最小で
    ps->v = v / 2;                                              // 補正
    pd->v = v;                                                  // 
    if( ( h % 4 ) == 0                                          // 水平幅が4で割り切れて
      && ( ps->inc % 4 ) == 0 && ( pd->inc % 4 ) == 0           // 増加幅が4で割り切れて
      && ( ps->adr % 4 ) == 0 && ( pd->adr % 4 ) == 0 ){        // アドレスも4で割り切れる場合
        copyFieldFrameBase( (long*)ps->adr, (long*)pd->adr,     // 左記で高速に処理
            h / 4, v / 2, ps->inc / 4, pd->inc / 4 );           // 
    }else{                                                      // 高速化条件を満足しない場合
        return( MagnifyZoomInt( ps, pd, 1, 2 ) );               // 左記で縦に×2倍拡大
    }                                                           // 
    return( END_STI );                                          // 正常終了
}

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

(4-14-5-A)関数「int CopyFieldFrame()」の【関数名】説明

「Copy」は、勿論、カタカナ語のコピで「Field」画像から
「Frame」画像へのコピーするですが、簡単に記載した
「Field・Frame」は、一般的な英単語の意味で無く、
20世紀のアナログTV放送用語と言うかアナログ時代の
画像信号の用語です!デジタル映像時代の今でも引きずる
「インターレス」⇒デジタル映像規格で「1080i」=
所謂、1Kデジタルハイビジョン(今の通常デジタルTV)
の映像規格です!ここの「i」が「インターレス」=日本語
で「飛越走査=インターレース方式とは、走査線を1本
おきに飛ばして表示する方式です。」⇒メリット「
1フレームを奇数番号と偶数番号の2つに分け、それぞれを
順に表示することで1枚の画像を映し出す事で2倍の枚数の
動画を送る事が出来、動画のコマ数が倍に成りナダラカに
自然に変化する動画を送る事が出来る方法と静止画として止
めると縦方向に倍の解像度の画像が表示可能」とアナログ
映像信号時代の人間の目がチョロイ事を利用した誤魔化し
技術「アナログTV放送とは人間の目を如何に誤魔化すかが
本筋」です!と言う訳で「Frame」は、フレーム画像=偶奇
両方を含んだ高精細な画像で「Field」は奇数フィールド・
偶数フィールドと奇数番号と偶数番号の2つに分けた画像を
意味します!この関数「CopyFieldFrame()」は、フィールド
サイズの画像をフィールドサイズに伸張させる関数です!

(4-14-5-B)関数「int CopyFieldFrame()」の
【返値】説明

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

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!
ここでは、仮引数「TypeArray* ps,TypeArray* pd」が
エラー発生なら
「return(STI_ARY_5);」と両方の画像が1バイト単位画素
で無ければエラーが発生します!
★注意★他の項目はチェクしません!

(4-14-5-C)関数「int CopyFieldFrame()」の【仮引数】説明

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

「TypeArray* ps,」は、S画像で「Field」画像を示しま
す。詰り、奇遇のフィールド画像としてキャプチャーされ
た画像が格納されている1バイト(8ビット)型の整数値
画素画像です!
「TypeArray* pd,」は、D画像で「Frame」画像を示しま
す。詰り、フィールド画像を1ラインずつ縦方向に引き延
ばした結果画像が格納される1バイト(8ビット)型の
整数値画素画像です!

(4-14-5-D)関数「int CopyFieldFrame()」の【アルゴリズム】説明

){
    TypeArray   s;                                              // S:サイズ補正後
    TypeArray   d;                                              // D:サイズ補正後
    int         h;                                              // 水平幅
    int         v;                                              // 垂直幅

    if( ps->w != 1 || pd->w != 1 ){                             // 8ビット画像以外ならば
        return( STI_ARY_5 );                                    // 不正を返す
    }                                                           // 
    s     = *ps;                                                // S配列を補正する
    ps    = &s;                                                 // ため情報をコピー
    d     = *pd;                                                // D配列を補正する
    pd    = &d;                                                 // ため情報をコピー
    h     = ( ps->h < pd->h ) ? ps->h : pd->h;                  // 水平幅を最小で
    ps->h = h;                                                  // 補正
    pd->h = h;                                                  // 
    v     = ps->v * 2;                                          // S画像の垂直幅×2
    v     = ( v < pd->v ) ? v : pd->v;                          // 垂直幅を最小で
    ps->v = v / 2;                                              // 補正
    pd->v = v;                                                  // 
    if( ( h % 4 ) == 0                                          // 水平幅が4で割り切れて
      && ( ps->inc % 4 ) == 0 && ( pd->inc % 4 ) == 0           // 増加幅が4で割り切れて
      && ( ps->adr % 4 ) == 0 && ( pd->adr % 4 ) == 0 ){        // アドレスも4で割り切れる場合
        copyFieldFrameBase( (long*)ps->adr, (long*)pd->adr,     // 左記で高速に処理
            h / 4, v / 2, ps->inc / 4, pd->inc / 4 );           // 
    }else{                                                      // 高速化条件を満足しない場合
        return( MagnifyZoomInt( ps, pd, 1, 2 ) );               // 左記で縦に×2倍拡大
    }                                                           // 
    return( END_STI );                                          // 正常終了
}

ローカル変数

){
    TypeArray   s;                                              // S:サイズ補正後
    TypeArray   d;                                              // D:サイズ補正後
    int         h;                                              // 水平幅
    int         v;                                              // 垂直幅

「TypeArray s;」は、内部でサイズを補正したS画像
「TypeArray d;」は、内部でサイズを補正したD画像
「int h;」は仮引数「TypeArray* ps,TypeArray* pd」
とSD画像の水平幅の最小値と実際に有効な水平幅です!
「int v;」は仮引数「TypeArray* ps」とS画像の
垂直幅×2とフィールドからフレームに引き延ばした
垂直幅と仮引数「TypeArray* pd」D画像との垂直幅の
最小値と実際に有効な垂直幅です!

アルゴリズムコード

    if( ps->w != 1 || pd->w != 1 ){                             // 8ビット画像以外ならば
        return( STI_ARY_5 );                                    // 不正を返す
    }                                                           // 
    s     = *ps;                                                // S配列を補正する
    ps    = &s;                                                 // ため情報をコピー
    d     = *pd;                                                // D配列を補正する
    pd    = &d;                                                 // ため情報をコピー
    h     = ( ps->h < pd->h ) ? ps->h : pd->h;                  // 水平幅を最小で
    ps->h = h;                                                  // 補正
    pd->h = h;                                                  // 
    v     = ps->v * 2;                                          // S画像の垂直幅×2
    v     = ( v < pd->v ) ? v : pd->v;                          // 垂直幅を最小で
    ps->v = v / 2;                                              // 補正
    pd->v = v;                                                  // 
    if( ( h % 4 ) == 0                                          // 水平幅が4で割り切れて
      && ( ps->inc % 4 ) == 0 && ( pd->inc % 4 ) == 0           // 増加幅が4で割り切れて
      && ( ps->adr % 4 ) == 0 && ( pd->adr % 4 ) == 0 ){        // アドレスも4で割り切れる場合
        copyFieldFrameBase( (long*)ps->adr, (long*)pd->adr,     // 左記で高速に処理
            h / 4, v / 2, ps->inc / 4, pd->inc / 4 );           // 
    }else{                                                      // 高速化条件を満足しない場合
        return( MagnifyZoomInt( ps, pd, 1, 2 ) );               // 左記で縦に×2倍拡大
    }                                                           // 
    return( END_STI );                                          // 正常終了
}

「if(ps->w!=1||pd->w!=1){return(STI_ARY_5);}」は、
仮引数「TypeArray* ps,TypeArray* pd」とSD画像情報
の内、エラー検査としてSD両方画像画素が1バイト整数で
を検査します!★注意★他の検査は行いません!
「s=ps;ps=&s;d=pd;pd=&d;」は、
仮引数「TypeArray ps,TypeArray pd」とSD画像情報
をローカル変数「TypeArray s;TypeArray d;」に内容を
コピーし、内部でのポインタの値に仮引数のポインタを付け
替えます!
「h=(ps->h<pd->h)?ps->h:pd->h;ps->h=h;pd->h=h;」は、
SD画像情報の有効(最小)な水平幅を算出しローカルな
それぞれの画像情報にセット
「v=ps->v*2;v=(v<pd->v)?v:pd->v;」は、SD画像情報の
有効(最小)な垂直幅の算出です!留意して頂きたいのは、
奇遇のフィールド画像からフレーム画像に変換する為に倍の
サイズに垂直幅をする必要が有ると言う事です!
「ps->v=v/2;pd->v=v;」は、「ps->v=v/2;」とS画像が
フィールド画像なので垂直幅/2をセットする事に留意して
頂きたい!
「if(・・条件・・){copyFieldFrameBase(・・実引数・・);
}else{return(MagnifyZoomint(・・実引数・・);}」は、
条件「if((h%4)==0&&(ps->inc%4)==0&&(pd->inc%4)==0
&&(ps->adr%4)==0&&(pd->adr%4)==0)」と
「long型=4バイト」扱えるメモリの区切りと認識したら
高速に動作出来る関数「copyFieldFrameBase()」成立で実行する事を示します!
この・・実引数・・は、「(long *)ps->adr,
(long *)pd->adr,h/4,v/2,ps->inc/4,pd->inc/4」と水平幅
方向(増加幅も含む)のパラメータを/4する事で「
long型=4バイト」に合わせます!
「v/2」はフィールドの水平幅=ライン数を示します!
「}else{・・以降・・}」は、条件不成立≪関数「
copyFieldFrameBase()」が使えない時の処理≫で
「return(MagnifyZoomint(ps,pd,1,2));」とリターン構文
の中で関数「MagnifyZoomint(ps,pd,1,2));」で垂直方向に
×2倍の画像を作成します!
「return(END_STI);」は、関数の正常終了です!

(4-14-6)関数「int
RepairImage(TypeArray* pa,
int tbl[],int n,int mode{・・・}」の説明

int             CopyClear::RepairImage(                         
    TypeArray*  pa,                                             // 配列
    int         tbl[],                                          // 欠陥場所テーブル
    int         n,                                              // 欠陥個数
    int         mode                                            // 修復モード
){
    Sort( 0, tbl, n );                                          // 昇順に欠陥場所をソート
    if( mode == 0 ){                                            // モード0なら
        return( repair0Image( pa, tbl, n ) );                   // 左記で処理
    }else if( mode == 1 ){                                      // モード1なら
        return( repair1Image( pa, tbl, n ) );                   // 左記で処理
    }else{                                                      // 上記以外
        return( STI_FLG );                                      // 左記を返す
    }                                                           // 
}

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

(4-14-6-A)関数「int RepairImage()」の
【関数名】説明

「Repair」は、英単語「Repair」で修理、カタカナ語でも
「リペア」と修理修繕及び補正を意味します!
「Image」は、勿論、画像でココでは、ラインセンサカメラ
の欠陥を補正する為に作成された特殊目的です!
具体的な用途としてADS社が新日鉄大分製鉄所の目視工程
でのスラブ≪製鉄生産時の鋼鉄の塊として巨大な岩片的な鉄
のマダ高熱を発する塊≫検査工程のスラブが巨大ローラー
コンベアー(ベルトコンベヤーの超巨大なバージョン)で
流れる物を人手の検査≪スラブの流れる現場の上に橋を渡し
て人間が乗り観察と落ちたら大火傷必須現場≫の代りに高精
細一次元ラインセンサーカメラで水平方向をスキャンし、
垂直方向はローラーにロータリーエンコーダーと言う回転数
とか回転角度を数値データ的にパルスカウントで出力する
機構を利用して縦横に長大な画像をデジタル的に記録させ、
同時に記録させた画像をモニター画面でリアルタイム表示や
巻き戻し観測する装置の発注を受けた時に当時の出始めた
ラインセンサーカメラに画素欠陥が有る為に補正する必要が
有り作成した特殊な専門用途です!
☆備考☆特殊用途ですが、似たような処置を行う必要が出る
と思いますのでライブラリに残しました!

(4-14-6-B)関数「int RepairImage()」の
【返値】説明

int             CopyClear::RepairImage(                         
    TypeArray*  pa,                                             // 配列
    int         tbl[],                                          // 欠陥場所テーブル
    int         n,                                              // 欠陥個数
    int         mode                                            // 修復モード
){

関数の返値(リターン・バリュー)として整数型「int 」で
関数実行時のステータス≪実行成功=「END_STI」、
エラーは、解説『エラーコード等各種単純定義』
「3.ステータス情報」に記載して居ます≫ので参考にし
て下さい!
ここでは、仮引数「int mode」が「0、1」の指定外の
値なら「STI_FLG」とエラー発生「return(STI_FLG);」とし
ます!
★注意★他の項目は内部で呼び出すサブルーチンで返します

(4-14-6-C)関数「int RepairImage()」の【仮引数】説明

int             CopyClear::RepairImage(                         
    TypeArray*  pa,                                             // 配列
    int         tbl[],                                          // 欠陥場所テーブル
    int         n,                                              // 欠陥個数
    int         mode                                            // 修復モード
){

「TypeArray* pa,」は、画像と言う依りも「一次元配列」
としてラインセンサーカメラでの画像を示します。詰り、
オリジナルカメラの画素情報としてキャプチャーされた画像
が格納されている1バイト(8ビット)型の整数値画素画像
です!
「int tbl[],」は、補正情報の入って居る配列を示します。
詰り、補正データがラインセンサーカメラに対応する量有り
それでサブルーチンで示した方法で補正処理します!
「int n,」は、補正情報の入って居る配列のサイズ(個数)
です!
「int mode」は、補正方法を示すサブルーチンの選択肢で
す!

(4-14-6-D)関数「int RepairImage()」の【アルゴリズム】説明

){
    Sort( 0, tbl, n );                                          // 昇順に欠陥場所をソート
    if( mode == 0 ){                                            // モード0なら
        return( repair0Image( pa, tbl, n ) );                   // 左記で処理
    }else if( mode == 1 ){                                      // モード1なら
        return( repair1Image( pa, tbl, n ) );                   // 左記で処理
    }else{                                                      // 上記以外
        return( STI_FLG );                                      // 左記を返す
    }                                                           // 
}

「Sort(0,tbl,n);」は、補正テーブル配列を昇順ソート
します!
「if(mode==0){・・左記条件成立1・・;}
else if(mode==1){・・左記条件成立2・・;}
}else{return(STI_FLG);}」は、条件「mode==0」の時に
成立1「return(repair0Image(pa,tbl,n));」と関数実行
「repair0Image(pa,tbl,n)」で処理し、返値は、
リターン文で返し、条件「mode==1」の時に
成立2「return(repair1Image(pa,tbl,n));」と関数実行
「repair1Image(pa,tbl,n)」で処理し、返値は、
リターン文で返し、何方も非成立ならば「
}else{return(STI_FLG);」とエラー「STI_FLG」を関数の
値として返します!

3月15日分迄の講義とします!本日の講義はココまでと
します!記載しているライブラリ作者の私でも疲れたの
だから、新しい概念に接して居る受講生の皆様もお疲れと
思います!オマケにNoteサーバーが、人気に成ったのか
想定外に重たく、追加編集が遣り難く成り追加する事が
出来ません!

続きは、「解説クラスCopyClear(11)」に
成ります!
(11)」では、関数「Convert()」の詳細な
「名称由来・仮引数・アルゴリズム」の解説と主に画像処理
ライブラリとしての使用方法を例文を記載して解説して行く
予定です!関数「Convert()」は、単純なクリアやコピーで
無く、画像を変換≪LUT変換と言う手法について≫解説を
行います!引き続き御贔屓して受講して下さい!

文末


この記事が気に入ったらサポートをしてみませんか?