2011年4月21日木曜日

THEMA: テーマ別まとめ

本ブログでアップされているファイル等:ダウンロード一覧

ユーティリティ
cpp2html:C言語ソースファイルからHTMLファイルへの変換
 cpp2html:C言語ソースファイルからHTMLファイルへの変換を実装する例です。
cpp2html クラスを利用した HTML 出力フォーマットの変更
 cpp2html クラスを利用した HTML 出力のフォーマットを変更する例です。
html2txt: HTML ファイルからテキスト文章の抽出
 html2txt: HTML ファイルからテキスト文章を抽出する例です。
バイナリファイル対応の head コマンド
 バイナリファイルにも対応した head コマンドの例題です。
バイナリファイル対応の tail コマンド
 バイナリファイルにも対応した tail コマンドの例題です。
バイナリファイル対応の head コマンド/ファイルのメモリマッピング
 バイナリファイルにも対応した head コマンドの例題です。
バイナリファイル対応の tail コマンド/ファイルのメモリマッピング
 バイナリファイルにも対応した tail コマンドの例題です。

画像処理
PNM(Portable anymap ファイルフォーマット)の読み取り/編集/保存、BMPへの変換
 PNM 画像の読取/編集/保存例です。
ビットマップファイルの読み込み/編集/保存
 ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。
ビットマップファイルフォーマットのグレースケール化
 ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/グレースケール化の例です。
FFMPEG/libavcodec のインストール
 C言語から FFMPEG に含まれる libavcodec 等のライブラリを利用するためのインストール手順です。
libavcodec による動画のサムネイル作成
 動画ファイルから動画位置を0から1までの割合で指定し、サムネイルを作成し保存する例題です。

数値計算
最大値、最小値の計算例
 ファイルからデータを読み取り、データの最大値、最小値を計算する例です。
多倍長演算を利用した四則演算
 多倍長演算を利用した四則演算の例題です。
四面体の体積を求める/指定した点が四面体の中に含まれるかを確認する
 三次元空間内の4点 Pi (i=1,2,3,4) を頂点とする四面体の体積を求める例題です。
はさみうち法による平方根の解法
 はさみうち法と2分法による平方根の解法の例題です。
Newton 法による平方根の解法
 Newton 法により平方根を求める例題です。
Newton 法による平方根の解法2
 Newton 法により平方根を求める解法の例です。
台形方式/シンプソンの公式による積分例
 台形方式/シンプソンの公式、のアルゴリズムを用いた数値積分の例題です。
8次のニュートン・コーツによる積分例
 8次のニュートン・コーツのアルゴリズムを用いた数値積分の例題です。
行列積の計算、表示
 ファイルから2つの行列を読み込み、その積を求める例題です。
最大・最小・平均・標準偏差の計算
 最大・最小・平均・標準偏差を計算する例題です。
階乗の計算
 再帰呼び出しによる階乗の計算例です。
約数の計算
 整数値から約数を計算する例題です。
ユークリッドの互除法による最大公約数の計算
 ユークリッドの互除法による最大公約数の計算例です。
アセンブラによる足し算
 アセンブラによる足し算の例題です。
ビットシフトによる掛算
 ビットシフトによる掛算の例題です。
相関係数の計算
 相関係数の計算例です。
2次方程式の解法
 2次方程式の解を得る例題です。
相関行列(係数)の計算
 2つの変量から相関係数を計算し、相関行列を計算する例題です。
2項分布による確率計算
 2項分布を利用し確率を計算する例題です。
基礎統計量の計算
 統計に必要となる基礎的な統計量の計算と標準化されたデータ列に対する統計量の計算例です。
 (平均値,偏差平方和,分散,標準偏差,相関係数の計算,標準化)
2直線の交点の計算
 y=ax+b で定義される2直線をランダムに生成し、その2直線が交わる交点 (x,y) を求める例題です。
基数値を指定し、x 進数の文字列として出力
 2進数、8進数、10進数、16進数等の基数値を指定し、与えられた値を x 進数の文字列として出力する例題です。

順列、組み合わせ
STL を利用した順列、組み合わせの出力
 STL を利用した順列、組み合わせの出力例です。
組合せ数 (nCr) の計算
 組合せ数(nCr)の計算例です。
全ての順列、組み合わせを配列として取得
 全ての順列、組み合わせを配列として取得する例題です。

乱数発生
乱数発生例(整数)
 整数の乱数を発生する例題です。
乱数発生例(実数)
 乱数を発生する例題です。
重複なしの乱数発生
 重複なしの乱数を発生するための例題です。
重複なしの乱数発生(クラス化)
 重複なしの乱数を発生するための例題です。
乱数発生に関する考察
 標準関数(srand/rand)を使いましょう、と言う考察結果です。

時間計測
経過時刻の計算/出力
 経過時刻の計算/出力例です。
経過時刻の計算/出力(クラス化)
 経過時刻の計算/出力例です。
実行時間計測の方法
 実行時間を計測する方法についての例題です。

ソート
ソートアルゴリズムの比較
 ソートアルゴリズムを各種準備し(昇順、降順含む)、その計算時間を比較した例です。
 (シンプルソート、クイックソート、qsort)
クイックソートによるソート
 C言語の標準関数である qsort() 関数を用いずにクイックソートを行う例です。
qsort を用いたソート
 C言語の標準関数である qsort() 関数を用いたソートの例です。
構造体データの並べ替え(昇順、降順)
 構造体により定義されたデータを並べ替える例です(昇順、降順)。
構造体データの並べ替え
 構造体を利用した社内スタッフの整理例です。
2分木による番号データのソート
 入力したデータ(ファイル入力)から2分木を作成し、番号順にソートした結果を表示する例題です。

プロセス間通信
プロセス間通信 (fork,pipe) によるメッセージの送受信
 プロセス間通信 (fork,pipe) により、親子プロセス間にてメッセージの送受信を行う例です。
プロセス間通信 (リダイレクション (fork,pipe,dup)) によるメッセージの送受信
 プロセス間通信 (リダイレクション (fork,pipe,dup)) により、親子プロセス間にてメッセージの送受信を行う例です。
プロセス間通信 (双方向 (fork,pipe,socketpair)) によるメッセージの送受信
 プロセス間通信 (双方向 (fork,pipe,socketpair)) により、親子プロセス間にてメッセージの送受信を行う例です。
メッセージキューによるプロセス間通信
 メッセージキューによるプロセス間通信の例です。

プロセス操作
親・子プロセス間でのメモリ共有
 子プロセスを起動し、親・子プロセス間でメモリを共有しデータのやりとりを行う例題です。
子プロセスの起動
 fork 関数により子プロセスを起動し、別プロセスにて処理を開始するための例題です。
リダイレクション (dup,execlp) により標準入出力の変更
 リダイレクションにより標準入出力をファイルとする例題です。
リダイレクション (fork,pipe,dup,execlp) によるプロセスの連結
 リダイレクション (fork,pipe,dup,execlp) によりプロセスを連結し、出力する例題です。
mysystem 関数の実装 (fork,execlp)
 system 関数と同等の機能を有する関数 (mysystem) を実装する例題です。
mypopen 関数の実装 (fork,pipe,dup,execlp)
 プロセス間通信、リダイレクション、パイプ処理等により、popen, pclose 関数を実装する例題です。
プロセスを起動し結果を文字列として取得 (fork,pipe,dup,execlp)
 プロセスを起動し結果を文字列として取得する例です。
プロセスを起動し結果を文字列として取得 (popen/pclose)
 プロセスを起動し結果を文字列として取得する例です。

ネットワーク
ホスト名からIPアドレスの取得
 ホスト名からIPアドレスを取得する例です。
文字列からプライベートIPアドレスの判別
 文字列からプライベートIPアドレスかどうかを判定する例題です。
TCP/IP を利用したソケット通信によるサーバー/クライアント通信
 TCP/IP を利用したソケット通信によるサーバー/クライアント通信例です。
高水準入出力関数を利用したソケット通信
 高水準入出力関数を利用したソケット通信の例です。
UDP を利用した syslog 送信
 UDP を利用した syslog 送信の例です。

CSVファイル
トークン毎のデータ抜き出し
 トークン毎にデータを抽出し表示する例です。
CSV ファイルの行と列を入れ替え
 CSVファイルを読み込み、行と列を入換えて出力する例題です。
CSV ファイルのデータ内容に合わせて2次元配列の動的確保 (int 型)
 CSV ファイルのデータ内容に合わせて2次元配列を動的に確保し、表示する例題です。
CSV ファイルのデータ内容に合わせて2次元配列の動的確保 (int, double 型)
 CSV ファイルのデータ内容に合わせて2次元配列を動的に確保し、表示する例題です。
CSV ファイルのデータ内容に合わせて3次元文字配列の動的確保 (char 型)
 CSV ファイルのデータ内容に合わせて3次元文字配列を動的に確保し、表示する例題です。

その他
ファイルサイズの取得
 ファイルサイズの取得例です(stat 関数とファイルポインタの位置からの計算の速度比較)。
CRC の計算
 ランダムに生成された数値データに対し、誤りチェックのためのCRCを計算する例題です。
XOR和によるチェックサムの計算
 データを送受信する際の誤り検出方法の一つであるチェックサムを計算し、配列に格納する例題です。
SHA-1 によるハッシュ値の計算
 SHA-1 によるハッシュ値の計算の例です。
MD5 によるハッシュ値の計算
 MD5 によるハッシュ値の計算の例です。


気になるテーマや今後の課題等
・行列演算のライブラリ化
・16進数→10進数への変換のソース等をまとめ直し(UTFコードの読み取りも合わせて)
・MFCのアンチョコなんかもチラホラ貼っていこうかなと。

こういうのをまとめて欲しいってのがあればコメなんか募集です。

2011年4月18日月曜日

テキストファイルを区切り文字ごとに分割し、禁句が含まれる文章を除外

テキストファイルを区切り文字ごとに分割し、禁句が含まれる文章を除外する例題です。

本記事末にある文章を区切り文字毎に分割し文字配列として記憶した後、その配列ごとに禁句が含まれるかチェックし、表示する、しないを選択しています。

処理の流れとしては、
1. テキストファイルの内容を文字列として読み込み
2. 文字列から区切りの数を数える
3. 区切り分の2次元文字配列を準備
4. 区切り文字ごとに文字列を配列に記憶
5. それぞれの文字配列ごとにタブーワードが含まれるかチェックし表示
という形になります。


実行結果
% ./list_xxx
0: 多倍長演算を利用した四則演算
Posted: 2011-04-18 01:40:39 UTC+09:00
多倍長演算を利用した四則演算の例題です。 20 桁ほどの計算を行っていますが、関数電卓等で計算できる範囲になりますので、結果を確かめてみてください。 #include #define ORDER 20 #define N ((ORDER-1)/4+1) void addLDV(short* a, short* b, short* c); void subLDV(short* a, short* b, short* c); void mulLDV(short* a, short b, short* c); void divLDV(short* a, short b, short* c); void printLDV(short* c); int main(int argc, int argv) { short a[N+2] = {


1: ファイル中から文字列を検索し、文字列を追加/置換
Posted: 2011-04-18 01:33:05 UTC+09:00
ファイル中から文字列を検索し、文字列を追加/置換する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndReplaceString(char* buf, char* find, char* repstr); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr


2: ファイル中から文字列を検索し、文字列を追加
Posted: 2011-04-18 01:35:01 UTC+09:00
ファイル中から文字列を検索し、文字列を追加する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; char *p; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr = "desu"; char buf[512]; printf("search


3: 指定した文字列の後ろに文字列を追加
Posted: 2011-04-17 23:34:31 UTC+09:00
指定した文字列の後ろに文字列を追加し、新しい文字列として取得する例題です。 #include #include #include #define STRING "Hello World!!" char* FindAndInsertString(char* buf, char* find, char* insert) { char* newstring; char* sp = strstr(buf,find); if ( sp == NULL ) return buf; sp += strlen(find); newstring = (char*)calloc(sizeof(char),(strlen(buf)+strlen(insert)+1)); strncpy(newstring,buf,strlen(buf)-


5: ビットマップファイルの読み込み/編集/保存
Posted: 2011-04-17 02:27:06 UTC+09:00
ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。 ビットマップはそれぞれの色毎に表示、編集することが可能となっています。例題では、引数に -r や -g を与えると、色反転、ガンマ補正を行うことができます。また、-o/-b により編集を行った画像を指定のビット数で保存します(16bit:RGB565/24bit:RGB888/32bit:RGBA8888 BMP)。 ビットマップは1ライン当たりのデータ数が4Byte(long)の倍数に限られているため##データの読取には注意が必要です。1ラインが4で割り切れない場合、足りないバイト数(足りない部分はパディングビット=0が詰め込まれている)を加えて計算する必要が##ります。具体的には、

%

document.txt
●多倍長演算を利用した四則演算
Posted: 2011-04-18 01:40:39 UTC+09:00
多倍長演算を利用した四則演算の例題です。 20 桁ほどの計算を行っていますが、関数電卓等で計算できる範囲になりますので、結果を確かめてみてください。 #include #define ORDER 20 #define N ((ORDER-1)/4+1) void addLDV(short* a, short* b, short* c); void subLDV(short* a, short* b, short* c); void mulLDV(short* a, short b, short* c); void divLDV(short* a, short b, short* c); void printLDV(short* c); int main(int argc, int argv) { short a[N+2] = {

●ファイル中から文字列を検索し、文字列を追加/置換
Posted: 2011-04-18 01:33:05 UTC+09:00
ファイル中から文字列を検索し、文字列を追加/置換する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndReplaceString(char* buf, char* find, char* repstr); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr

●ファイル中から文字列を検索し、文字列を追加
Posted: 2011-04-18 01:35:01 UTC+09:00
ファイル中から文字列を検索し、文字列を追加する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; char *p; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr = "desu"; char buf[512]; printf("search

●指定した文字列の後ろに文字列を追加
Posted: 2011-04-17 23:34:31 UTC+09:00
指定した文字列の後ろに文字列を追加し、新しい文字列として取得する例題です。 #include #include #include #define STRING "Hello World!!" char* FindAndInsertString(char* buf, char* find, char* insert) { char* newstring; char* sp = strstr(buf,find); if ( sp == NULL ) return buf; sp += strlen(find); newstring = (char*)calloc(sizeof(char),(strlen(buf)+strlen(insert)+1)); strncpy(newstring,buf,strlen(buf)-

●PNM(Portable anymap ファイルフォーマット)の読み取り/編集/保存、BMPへの変換
Posted: 2011-04-17 02:23:39 UTC+09:00
PNM 画像の読取/編集/保存例です。 PNM(portable anymap ファイルフォーマット)は、pbm(portable bitmap)、pgm(portable graymap)、ppm(portable pixmap)の各画像フォーマットを総称した名前です。 PNM のファイル形式はテキスト/バイナリ形式を選択することにより、メモ帳等でも簡単に編集することが可能です。 その形式には以下の6種類があります。 P1 (PBM) 2値画像 テキスト形式 P2 (PGM) 濃淡画像 テキスト形式 P3 (PPM) カラー画像 テキスト形式 P4 (PBM) 2値画像 バイナリ形式 P5 (PGM) 濃淡画像 バイナリ形式 P6 (PPM) カラー画像 バイナリ形式 P4〜P6 の形式では画像のヘッダ部分を除いた画像データ部を

●ビットマップファイルの読み込み/編集/保存
Posted: 2011-04-17 02:27:06 UTC+09:00
ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。 ビットマップはそれぞれの色毎に表示、編集することが可能となっています。例題では、引数に -r や -g を与えると、色反転、ガンマ補正を行うことができます。また、-o/-b により編集を行った画像を指定のビット数で保存します(16bit:RGB565/24bit:RGB888/32bit:RGBA8888 BMP)。 ビットマップは1ライン当たりのデータ数が4Byte(long)の倍数に限られているため、データの読取には注意が必要です。1ラインが4で割り切れない場合、足りないバイト数(足りない部分はパディングビット=0が詰め込まれている)を加えて計算する必要があります。具体的には、

テキストファイルを区切り文字ごとに分割

テキストファイルを区切り文字ごとに分割する例題です。

例として、本記事の最後に示すテキストファイルのような内容ですが、本ブログのRSSの内容で、各記事毎に
●タイトル、記事の概要
と言うように区切られています。

概要の文章の部分は改行文字等も含むため、1行ごとに処理を行うような文字の分割では処理ができません。
そこで、テキストファイルの全文を一度文字列として読み込み、その文字列に対して区切り文字を検索して分割する必要があります。


実行結果
% ./list_xxx
0: 多倍長演算を利用した四則演算
Posted: 2011-04-18 01:40:39 UTC+09:00
多倍長演算を利用した四則演算の例題です。 20 桁ほどの計算を行っていますが、関数電卓等で計算できる範囲になりますので、結果を確かめてみてください。 #include #define ORDER 20 #define N ((ORDER-1)/4+1) void addLDV(short* a, short* b, short* c); void subLDV(short* a, short* b, short* c); void mulLDV(short* a, short b, short* c); void divLDV(short* a, short b, short* c); void printLDV(short* c); int main(int argc, int argv) { short a[N+2] = {


1: ファイル中から文字列を検索し、文字列を追加/置換
Posted: 2011-04-18 01:33:05 UTC+09:00
ファイル中から文字列を検索し、文字列を追加/置換する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndReplaceString(char* buf, char* find, char* repstr); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr


2: ファイル中から文字列を検索し、文字列を追加
Posted: 2011-04-18 01:35:01 UTC+09:00
ファイル中から文字列を検索し、文字列を追加する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; char *p; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr = "desu"; char buf[512]; printf("search


3: 指定した文字列の後ろに文字列を追加
Posted: 2011-04-17 23:34:31 UTC+09:00
指定した文字列の後ろに文字列を追加し、新しい文字列として取得する例題です。 #include #include #include #define STRING "Hello World!!" char* FindAndInsertString(char* buf, char* find, char* insert) { char* newstring; char* sp = strstr(buf,find); if ( sp == NULL ) return buf; sp += strlen(find); newstring = (char*)calloc(sizeof(char),(strlen(buf)+strlen(insert)+1)); strncpy(newstring,buf,strlen(buf)-


4: PNM(Portable anymap ファイルフォーマット)の読み取り/編集/保存、BMPへの変換
Posted: 2011-04-17 02:23:39 UTC+09:00
PNM 画像の読取/編集/保存例です。 PNM(portable anymap ファイルフォーマット)は、pbm(portable bitmap)、pgm(portable graymap)、ppm(portable pixmap)##各画像フォーマットを総称した名前です。 PNM のファイル形式はテキスト/バイナリ形式を選択することにより、メモ帳等でも簡単に編集することが可能です。 その形式には以下の6種類があります。 P1 (PBM) 2値画像 テキスト形式 P2 (PGM) 濃淡画像 テキスト形式 P3 (PPM) カラー画像 テキスト形式 P4 (PBM) 2値画像 バイナリ形式 P5 (PGM) ##淡画像 バイナリ形式 P6 (PPM) カラー画像 バイナリ形式 P4〜P6 の形式では画像のヘッダ部分を除いた画像データ部を


5: ビットマップファイルの読み込み/編集/保存
Posted: 2011-04-17 02:27:06 UTC+09:00
ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。 ビットマップはそれぞれの色毎に表示、編集することが可能となっています。例題では、引数に -r や -g を与えると、色反転、ガンマ補正を行うことができます。また、-o/-b により編集を行った画像を指定のビット数で保存します(16bit:RGB565/24bit:RGB888/32bit:RGBA8888 BMP)。 ビットマップは1ライン当たりのデータ数が4Byte(long)の倍数に限られているため##データの読取には注意が必要です。1ラインが4で割り切れない場合、足りないバイト数(足りない部分はパディングビット=0が詰め込まれている)を加えて計算する必要が##ります。具体的には、
%

document.txt
●多倍長演算を利用した四則演算
Posted: 2011-04-18 01:40:39 UTC+09:00
多倍長演算を利用した四則演算の例題です。 20 桁ほどの計算を行っていますが、関数電卓等で計算できる範囲になりますので、結果を確かめてみてください。 #include #define ORDER 20 #define N ((ORDER-1)/4+1) void addLDV(short* a, short* b, short* c); void subLDV(short* a, short* b, short* c); void mulLDV(short* a, short b, short* c); void divLDV(short* a, short b, short* c); void printLDV(short* c); int main(int argc, int argv) { short a[N+2] = {

●ファイル中から文字列を検索し、文字列を追加/置換
Posted: 2011-04-18 01:33:05 UTC+09:00
ファイル中から文字列を検索し、文字列を追加/置換する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndReplaceString(char* buf, char* find, char* repstr); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr

●ファイル中から文字列を検索し、文字列を追加
Posted: 2011-04-18 01:35:01 UTC+09:00
ファイル中から文字列を検索し、文字列を追加する例題です。 1行毎に処理を行っていますが、複数マッチする場合にも対応しています。 #include #include #include void chop_crlf(char* buf); char* FindAndInsertString(char* buf, char* find, char* insert); int main(int argc, char* argv[]) { FILE *fp; char *p; const char* ifile = "reidai.txt"; const char* schstr = "pen"; const char* insstr = "desu"; char buf[512]; printf("search

●指定した文字列の後ろに文字列を追加
Posted: 2011-04-17 23:34:31 UTC+09:00
指定した文字列の後ろに文字列を追加し、新しい文字列として取得する例題です。 #include #include #include #define STRING "Hello World!!" char* FindAndInsertString(char* buf, char* find, char* insert) { char* newstring; char* sp = strstr(buf,find); if ( sp == NULL ) return buf; sp += strlen(find); newstring = (char*)calloc(sizeof(char),(strlen(buf)+strlen(insert)+1)); strncpy(newstring,buf,strlen(buf)-

●PNM(Portable anymap ファイルフォーマット)の読み取り/編集/保存、BMPへの変換
Posted: 2011-04-17 02:23:39 UTC+09:00
PNM 画像の読取/編集/保存例です。 PNM(portable anymap ファイルフォーマット)は、pbm(portable bitmap)、pgm(portable graymap)、ppm(portable pixmap)の各画像フォーマットを総称した名前です。 PNM のファイル形式はテキスト/バイナリ形式を選択することにより、メモ帳等でも簡単に編集することが可能です。 その形式には以下の6種類があります。 P1 (PBM) 2値画像 テキスト形式 P2 (PGM) 濃淡画像 テキスト形式 P3 (PPM) カラー画像 テキスト形式 P4 (PBM) 2値画像 バイナリ形式 P5 (PGM) 濃淡画像 バイナリ形式 P6 (PPM) カラー画像 バイナリ形式 P4〜P6 の形式では画像のヘッダ部分を除いた画像データ部を

●ビットマップファイルの読み込み/編集/保存
Posted: 2011-04-17 02:27:06 UTC+09:00
ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。 ビットマップはそれぞれの色毎に表示、編集することが可能となっています。例題では、引数に -r や -g を与えると、色反転、ガンマ補正を行うことができます。また、-o/-b により編集を行った画像を指定のビット数で保存します(16bit:RGB565/24bit:RGB888/32bit:RGBA8888 BMP)。 ビットマップは1ライン当たりのデータ数が4Byte(long)の倍数に限られているため、データの読取には注意が必要です。1ラインが4で割り切れない場合、足りないバイト数(足りない部分はパディングビット=0が詰め込まれている)を加えて計算する必要があります。具体的には、

多倍長演算を利用した四則演算

多倍長演算を利用した四則演算の例題です。

20 桁ほどの計算を行っていますが、関数電卓等で計算できる範囲になりますので、結果を確かめてみてください。

実行結果

ファイル中から文字列を検索し、文字列を追加/置換

ファイル中から文字列を検索し、文字列を追加/置換する例題です。

1行毎に処理を行っていますが、複数マッチする場合にも対応しています。

実行結果

ファイル中から文字列を検索し、文字列を追加

ファイル中から文字列を検索し、文字列を追加する例題です。

1行毎に処理を行っていますが、複数マッチする場合にも対応しています。

実行結果

2011年4月17日日曜日

指定した文字列の後ろに文字列を追加

指定した文字列の後ろに文字列を追加し、新しい文字列として取得する例題です。


実行結果

2011年4月16日土曜日

PNM(Portable anymap ファイルフォーマット)の読み取り/編集/保存、BMPへの変換

PNM 画像の読取/編集/保存例です。

PNM(portable anymap ファイルフォーマット)は、pbm(portable bitmap)、pgm(portable graymap)、ppm(portable pixmap)の各画像フォーマットを総称した名前です。
PNM のファイル形式はテキスト/バイナリ形式を選択することにより、メモ帳等でも簡単に編集することが可能です。

その形式には以下の6種類があります。
P1 (PBM) 2値画像 テキスト形式
P2 (PGM) 濃淡画像 テキスト形式
P3 (PPM) カラー画像 テキスト形式
P4 (PBM) 2値画像 バイナリ形式
P5 (PGM) 濃淡画像 バイナリ形式
P6 (PPM) カラー画像 バイナリ形式

P4〜P6 の形式では画像のヘッダ部分を除いた画像データ部をバイナリ形式で出力しなければならないので、メモ帳等での編集は無理ですが、P1〜P3 の形式はテキスト形式で画像の輝度・色情報(R,G,B)を書き込むことができ、メモ帳等で編集することが可能です。

ファイルフォーマットは以下のようなものです。
Pn | → マジックナンバー: P1〜P6
5 5 +--- ヘッダ部 → 横幅 縦幅
5 | → 最大輝度値(PBMでは必要ない)
0 1 0 1 0 |
0 1 0 1 0 |
0 1 0 1 0 +---画像データ部(PBM,PGMの場合)
0 1 0 1 0 | (PPMでは R,G,B の順に記述)
0 1 0 1 0 |

例題では、PGM/PPM 画像の書き出し、PPM 画像の読み込み、編集した画像の BMP への出力を行っています。

ソース等をまとめたもの:DL(PPM 画像含む)

編集や閲覧用のソフトが手近にない場合は、Windows では Susie/Irfanview、OSX/Linux では GIMP2 にてお試しください。

pnm_output.cpp

pnm_lib.h

pnm_lib.cpp
実行結果

処理結果(grayscale.bmp)

処理結果(colorscale.bmp)

処理結果(output.bmp)

2011年4月15日金曜日

ビットマップファイルの読み込み/編集/保存

ビットマップファイルフォーマット(8bit:256パレットカラー/16bit:RGB565/24bit:RGB888/32bit:RGBA8888)の画像の読取/編集/保存例です。

ビットマップはそれぞれの色毎に表示、編集することが可能となっています。
例題では、引数に -r や -g を与えると、色反転、ガンマ補正を行うことができます。
また、-o/-b により編集を行った画像を指定のビット数で保存します(16bit:RGB565/24bit:RGB888/32bit:RGBA8888 BMP)。

ビットマップは1ライン当たりのデータ数が4Byte(long)の倍数に限られているため、データの読取には注意が必要です。
1ラインが4で割り切れない場合、足りないバイト数(足りない部分はパディングビット=0が詰め込まれている)を加えて計算する必要があります。
具体的には、

bmp.cpp : LoadBMP() 関数内
// 1 ラインあたりのデータ数: 4byte 境界にあわせる
Line = (bmih.biWidth * bmih.biBitCount)/8;
if ( (Line%4) != 0 ) Line = ((Line/4)+1)*4;

のような計算が必要となります。
また、高さが負の値を取る場合もあるため、y 軸を反転して画素を取る工夫も行っています(DL先の書庫内:revdirection24bit.bmp)。

ソース等をまとめたもの:DL (8bit/16bit/24bit/32bit 画像含む)

16bit:RGB565 の画像の準備に手こずりましたが、GIMP2 が RGB565 の読み込み/書き出しに対応していますので、編集ソフト等をお持ちでない場合はそちらでお試しください。
16bit の画像編集は、Android や OpenGL を利用していると利用する機会も増えてきますので(処理も早くなりますし、見た目も 24bit と見劣りしない)、覚えておくとなかなかに便利です。
本例題は、16bit の BMP から 24/32bit の BMP への変換としても利用できます(8bit/16bit/24bit/32bit → 16/24/32bit)。

出力される拡張子 .pgm の画像形式は、グレイスケールの PNM(Portable anymap ファイルフォーマット)であり、テキスト形式で RGB データを出力しています(バイナリ形式で出力することもできます。)。
PNM の読み込み/編集/出力に関しては、こちらで
表示ソフトとしては、Windows (Susie/Irfanview etc.)、OSX (Graphic Converter)、GIMP2 は全OS、で利用できます。

bmploader.cpp
bmp.h
bmp.cpp
実行結果

元画像(RGB565:16bit)


処理結果(output.bmp:24bit)

2011年4月14日木曜日

親・子プロセス間でのメモリ共有

子プロセスを起動し、親・子プロセス間でメモリを共有しデータのやりとりを行う例題です。

例題では、親プロセスから生成された子プロセスは、親プロセスが持っていたメモリ(変数)をコピーし情報のやりとりを行っています。
その際、親・子プロセス両方から読み書き可能なメモリ領域を作って情報をやりとりする必要があります。
それを実現するのが共有メモリです。

共有メモリの取得後、削除せずに終了した場合、その共用メモリはOSが終了するまで残ってしまいます。
このようなメモリはipcsコマンドで見ることができ、ipcrmにより削除することが可能です。
(共有メモリを利用するプログラム起動中に ipcrm を行うと、release_sharemem 関数にて、"shmctl: Invalid argument" というようなエラーメッセージが表示されます。その辺はきちんと排他制御的なコードを考える必要はあります:セマフォ等)

今回の例題では a(int型)のデータのみ共用していますが、共有する情報は構造体にまとめて共有するのが便利であるため、共有メモリは構造体として宣言しています。

例題の動作は、親プロセスにより子プロセスが終了するのを待ち、a が 0 でなければプログラムを終了し、メモリを削除、a が 0 であれば、再びプロセスを作成し同じ処理を続行するようになっています。


例題に用いた関数は以下のもの。
shmget() 共有メモリの識別子を得る
shmat() 自プロセスのメモリとして割り当てる
shmdt() 自プロセスのメモリから外す
shmctl() 共有メモリの制御を行う(共有メモリの削除も可能)

子プロセスが起動した状態をアクティビティモニタにより確認した様子:

(Path Finder から tcsh を起動し、その後 make でソースをコンパイル・実行しているので、list_xxx のコマンドがそれ以降の階層に表示されており、さらに子プロセスが起動しているのが分かります。)


共有メモリを削除し忘れた場合の削除方法

実行結果

2011年4月9日土曜日

経過時刻の計算/出力

経過時刻の計算/出力例です。

計算が数日にも及んでしまう際、何日経過したかを書式付で出力します。
計算例では、"20041125172211"のように、
2004:年,11:月,25:日,17:時,22:分,11:秒
を記したテキストから経過時刻を計算しています。

strftime 関数により、struct tm 形式の時刻を"20041125172211"のような形に自由に整形することができます。


実行結果

四面体の体積を求める/指定した点が四面体の中に含まれるかを確認する

三次元空間内の4点 Pi (i=1,2,3,4) を頂点とする四面体の体積を求める例題です。

また、指定した点 Q がその四面体の中に存在するかを確認する方法についても考えています。

まず、四面体の体積に関する計算方法ですが、
CASIO の keisan の HP : http://keisan.casio.jp/
が役に立ちました。
トップページから空間幾何のリンクへ飛び、その中に四面体の体積の計算方法が記載されています。

点 A,B,C,P に対し、
A→B : b ベクトル
A→C : c ベクトル
A→P : p ベクトル
というベクトルを定義し、
体積 V = (p・(b×c))/6 (・は内積、×は外積)
という形で計算されます。

また、空間幾何のページを参考に、点(P)と平面(三角形ABC)の距離を求め、
体積 V = (底面積×高さ)/3
により計算しています。
底面積(三角形ABCの面積)は、ヘロンの公式により、
B→C : a ベクトル
C→A : b ベクトル
A→B : c ベクトル
s = (|a|+|b|+|c|) / 2
底面積 S = sqrt(s*(s-a)*(s-b)*(s-c))
により計算しています。

両者の計算が一致することを確認しています。

四面体の中に点 Q が存在するかどうかに関しては、
1. 点 Q と他4つの点 Pi を頂点とする4つの四面体の体積を求める
2. 元の四面体の体積と4つの四面体の体積が一致すれば、点 Q が四面体の内部に存在することになる
という確認方法をとっています。
文章だけでは確認しずらいと思いますので、実際に図を書いてみて確認して頂ければと思います。

ソース等をまとめたもの:DL


3dvector.h

3dvector.cpp
tetrahedron.cpp 実行結果

2011年4月8日金曜日

はさみうち法による平方根の解法

はさみうち法は、レギュラ・ファルシ (regula falsi) 法とも言います。
例題では、はさみうち法と2分法により平方根を求めています。

はさみうち法と2分法は、連続関数 f(x) と区間 a < = x < = b が与えられたとき、その区間で方程式 f(x)=0 の解を探す方法の一つです。

両端での関数値 f(a),f(b) は異符号でなければなりません。
2点 ([a,f(a)],[b,f(b)]) を直線で結び、それが x 軸と交わる点 c を求める形になります。
その点での関数値 f(c) が f(a) と同符号なら、解は c < x < b にあり f(c) が f(b) と同符号なら解は a < x < c にあります。
このようにして解の存在範囲を狭めることを繰り返します。
しかし、必ずしも2分法より早いとは限りません。
また、区間の両端での関数値の絶対値に大差があると、補間点 c が区間の端点に一致してしまいます。
このような場合は、c を強制的に極わずか (隣の不動小数点数まで) 移動します。

プログラムの tolerance は解の許容誤差(計算機イプシロンを利用)、戻り値は f(x)=0 の解、imax 回繰り返しても収束しないなら 2分法に切り換えます。
(imax=0 で呼び出せば最初から2分法になります。)

Newton 法 による解法に比べ、計算回数が多くなっていることは分かると思います。


実行結果

実行時間計測の方法

実行時間を計測する方法は各種存在していますが、例題では 4 種類の方法により計測しています。

clock/getrusage では、呼び出したプロセスの CPU 時間やリソース使用量が利用されるため、sleep/usleep 関数により CPU の利用を停止すると、その間の経過時間は計測されないので注意が必要です。

比較的長い時間の処理で、かつ I/O 等も含めたプログラム全体の処理を測定するには、時刻から経過時間を計測する gettimeofday を用いる方法が無難な方法になります。

times はシステムが起動した時間からのクロック数を返すため、gettimeofday と同様プログラムが CPU を利用しない間も、システム側が利用しているクロックを取得し、経過時間を取得することができます。


プログラム中の一部の処理において CPU 時間を測る場合、短い時間測定には getrusage を利用し、長い場合には、clock を使うのが良いかと思われます。

実際には、I/O 等も含めたプログラム全体の測定することが多いため、gettimeofday を利用することをお勧めします。

clock() : プログラムの使用したプロセス時間の近似値を返す(clock_t 単位の CPU 時間)。
times() : 過去のある時点から経過したクロック数を返す (clock_t 単位の CPU 時間)。
gettimeofday() : 時刻を取得する。
getrusage() : 資源の使用量を取得する。


例題では、Intel プロセッサにおける RDTSC (read-time stamp counter) を利用してクロック数を計測するための関数も用意しています。
これは、インラインアセンブラを利用し、CPU 内のカウンタを直接取得するような方法になります。


実行結果