
解説クラス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)』を
御贔屓下さい!