C++ Builder VCLでのファイル読み込み

C++ Builder VCLは MFCと異なる概念のGUIコンポーネントです どちらかと言えば Visual Basicに似たようなグラフィック・コンポーネントをフォームに配置し、それに対する event handlerを C++で記述していきます

MFCに慣れていると、全く別の世界なのでファイルからどのように読み込むのかすら分かりません まずいことに MFCと異なりユーザーの数が圧倒的に少ないためだと思うのですが、インターネット上に参考となる資料が少ないのです ファイルをどのように読み込めばよいのか調べた挙句数時間かかったのですが、ようやく次のようなプログラムで動作確認されました

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	char buff[100];
	FileOpenDialog1->Execute();
	ShowMessage(FileOpenDialog1->FileName);
	TFileStream *rFile;
	try {
		rFile = new TFileStream(FileOpenDialog1->FileName , fmOpenRead );
	} catch( ... ){
    // ファイルが開けなかった
		ShowMessage(FileOpenDialog1->FileName + "が開けませんでした。");
		return;
	}
// ファイルからデータを読み込みbuff変数に格納(最大100バイト)
	rFile->Read( buff, 100 );

/* ここからは読み込んだデータのデバッグ用のコード。読み込んだデータは文字列 と仮定する為、念のため最後に'\0'をつける。 */
	buff[99] = '\0';
	ShowMessage(buff);
                    // ファイルを閉じる
	delete rFile;
	rFile = NULL;

}

しかしこの使い方に慣れてしまえば MFCよりも圧倒的に簡単な操作で物事ができそうです

DICOM-XA Viewerでのメモリーリーク

何となく体裁が整ったきちんとリアルタイムの動画で動く DICOM-XA Viewerなのですが、そのUI部分は MFC (Microsoft Foundation Class)を用いて作成しています。もちろん重要なロジックは当方が 10年間の歳月をかけてつくりあげたものです。コンパイルして動作させても軽快に動きますが、VisualStudio debug modeでやると、最後に1KBぐらいの memory leakが検出されるのです。
ソースコードを追いながらその原因を探るのですが、分かりません。そもそも MFCを用いているのでどのように原因トレースすべきか判らないのです。それで Google博士に聞きました。Google博士はご機嫌斜めらしく、色々な聞き方をして、ようやくこのページにヒットしました。

ここに書いてあることも、普通は分かりにくいですよね。

#ifdef	__AFX_H__            // MFCのウィンドウを使う場合に限定しています
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
以上のコードを、すべてのソースコード (*.cpp) のヘッダファイルをインクルードしたあとに追加します。

などと書かれてもどこに書けば良いのか分かりませんよね。これについては、簡単に考えて、.cpp filesの #includeの行が無くなったらばその先頭に書き込むのです。自分が作成した全ての .cppファイルに書き込むのです。

そして、再度コンパイルして走らせました。そうしたらば、見事 Memory leakを引き起こしている命令行が分かりました。そこてら、色々考えてついに、RBitStream classに潜んでいたメモリーリークを突き止め、修正しました。

ああ めでたしめでたし

今、MFCから C++ Builderに開発環境を移行しようかと考えているところです。

C++ Builder

これまでC++のプログラムを書いてC++の勉強をする時にはほとんどの場合 VisualStudioを使用してきました そして、ときどきMacBook-Proでの OSXで XCodeの上で GCCやLLVMだっけなんだっけか とにかく純正に近いC++を使用してきました
もともとC++のプロの間では MicrosoftのC++ CompilerがC++の標準規格から外れる、という問題点が指摘されているのを知っていましたが、実際問題として Windows上で C++を用いて何らかのプログラムを作成する時には、やはりMicrosoft C++ (VisualStudio)という選択だったのです
以前より Borland社は非常に高機能なC++ Compilerを出していたのですが、現在はEmbarcarderoという会社に吸収されてしまいました そして、C++ BuilderというCompilerを世に出していたのです
その存在は依然から知っていましたが、どうしても踏み込めなかったのです しかし、ついにそのCompilerを昨日入手しました 標準C++によく合致しているそうです これからはこのComplierを用いて DICOM Viewerを作成しようと思っています

ついに動画出力に成功

各コマのDICOM XA画像出力に成功し、動画とすることは目前に迫っていました。動画化することに技術的難点があるとは考えませんでした。実際、MFC single document classを用いて実装し、ファイルからメモリに読み取り、フレームに分割する部分をCDocument classに実装し、一秒間15コマのタイマー割り込みと、画面に書き込む部分をCView classに実装し、エイヤッとコンパイルしたところ、見事に動画として動作しました。動画も軽快であり、画面のチラつきも無く、まだまだコマ数を増やせそうです。いやあ長い旅路でしたが、ようやく DICOM XA出力できるようになりました。
後は、DICOMとしてのタグの処理などを実装します。これは簡単ですが、ややこしい作業です。

やっと解決

DICOM XA Viewerが何とか走るようになりそうです 前日解決できなかった、あるフレームでは絵がビット崩れする現象の原因が特定できたのです
XA dataからBit入力して、Huffman codeを用いて暗号解読していく訳ですが、肝腎のHuffman codeが実はフレーム毎に変化していたのです いや、大体は変化せず、最初のフレームのHuffman codeがそのまま用いられるのですが、時に変化するのです だから、DHTからHuffman codeを解読せねばならないのです
その部分を書き直したところ下記のように先日ビット崩れしていたフレームもきちんと解読することに成功しました
DICOM_test4

DICOM_test5

DICOM_test6
あとはタイマー割り込みを実装して時間と共にフレームを書き換えるだけです
それはかつてブロック崩しを作成した時に実装した経験があるので簡単な筈なのですが・・・
実はすっかり忘れてしまい、今はどうやるやら全く判らなくなっているのです でもまあできるでしょう

まだ道は遠い

ようやく絵が出せるようになった DICOM-XA Viewerですが まだまだバグがありそうです
片っ端から、XA fileを開き、またコマを変えたりして見ているのですが 既にこんな異常が見つかりました
次に掲げてあるのが 001013XAというシーンの XA fileです このシーンは短く5コマしかありませんが、その中の 3コマ目、4コマ目、5コマ目を並べると以下のようになったのですが、これはあくまでも僕の Viewerのバグです 問題はバグがどこにあるのか現時点では皆目見当がつかない、ということです それに どうやってバグ潰しをすればいいのか? それも見当がつかないということです
いやもっと大きな問題は自由に思索する時間が無い、ということです 仕事に追われています
frame3
frame4
frame5

深刻な問題

本日深刻な問題を知りました 僕は Macbook-Proを使い、OSX10.8の上に、Parallels Desktopを用いて Windows7を走らせ、普段はその Windows7上で仕事やプログラムを書いています
CD/DVD読み込みの設定が、OSX優先となっていたため、DICOM-CD/DVDを挿入すると、自動的に OSX上の Osirixが立ち上がりファイルを読み込み、Windows7側では読み込めなかったのです
そこで、そうやって OSX上に読み込まれた DICOM-XA fileを Desktopにコピーしました Desktopに関しては両方のOSから普通に読み書きできるからです また読み込んだファイルは XAですから binary dataということになりますので、当然ながら Windows7上の binary editorでも読み込める筈です
ところがところが VisualStudio 2010内臓のbinary editorで開きに行くと開けないのです!!! Binary editorで開けないファイルがこの世に存在するなんて信じられません
ひっょとして、と思い、Google博士に聞いてみました そして、Parallelsを用いても Windows側で CD/DVDを読み込む方法を見つけました、そして Windows側でCD/DVDを開いてファイルを Desktopにコピーしたのです そうするとなんとなんと 今度は普通に Binary Editorで読み込めるのです
これってどういうこと? 同じDesktopに書き込んでいるのですから、少なくとも物理的ファイル・フォーマットの違いの問題ではありません なんかファイル・ヘッダーが違う関係で読み込めないのかなあ?
それぞれのOSの Binary Editorで開いてみて比較すればわかるのでしょうが・・・
こんなに深刻な問題につきあたるなんて想像していませんでした 

実際問題として一度 CD/DVDから Osirixに読み込んでしまえば、それをDICOM-XAで書きだしたとしても、本当に Windows上の DICOM Viewerで読めるのかどうか という深刻な問題を投げかけています 誰か試してみないですか?

成田到着

長ーい長ーい飛行の末に成田に到着しました 長かったです しかもこの間 あまり睡眠とっていません 例の DICOM-XA画像化に興奮し、プログラムばかりしていました やはり日本は暑いですねえ 極寒のサンパウロとはものすごく違います
これから夢は DICOM-XAの動画表示 あるいはインターフェースの実装 あるいはOSXへの移植 色々と課題があります とても楽しみですね

ついに絵が出た

ついについに DICOM-XAの一フレームを画像として出すことができました これまでの少なくとも 2006年から取り掛かってきた自分自身のプロジェクトがようやく実体化しつつあります
「DICOM-XAの Viewerを作ろう」と思い立ったのは、色々な理由がありました

  1. 我々からすれば謎の多い DICOM-XAを我々でも理解できるようにしたい そのためには自分自身でプログラムを書いて、てぎれば皆が理解し易いスクリプトで書き換え、それを公開したい
  2. 自分自身のC++の勉強のための題材としたい
  3. 自分自身何年かがかりの目標を持ちたい
  4. 自らの頭脳の限界に挑戦したい

こんなところでしょうか

それでも何回も何回も挫折したのです 色々な方々にご教授をお願いしました DICOM-XA Viewerを開発しておられるメーカーの方々にも質問を投げかけました しかし、何時も答えは曖昧なものでした そりゃあ彼らも必死で開発し、その心臓部のアルゴリズムは秘密にしたいと思います 仕方ありません

そんな中で ひょんなことで芝浦工業大学の先生方と知り合いとなり、T先生に核心的なヘルプを頂きました 流石に画像処理のプロ、僕が何年もかかっても解決できなかったことが、数日で解決しました でもただ言われるままにしているのではありません 自分で理解し、確認しながらの作業でした そして、サンパウロからドバイへの14時間の飛行機の中でついに絵が出ました 感激の瞬間でした これまでの少なくとも7年間に及ぶ苦労がやっと報われつつあるのです

でも、今後はパラパラ漫画にするために、タイマー割り込みをかけたり、動画とするためには色々な作業があります それがまた楽しみです さらには OSXにも移植したいと思います そして、それらの作業の中で理解を確実なものとして それを そうですねえ Visual Basicか、PHPあたりのスクリプト言語で書き直し、もちろんスピードの点で使い物にはならないでしょうが 公開したいと思います それではできた絵をここで初めて公開します

はじめて画像化できた DICOM-XAのフレーム
はじめて画像化できた DICOM-XAのフレーム

これからサンパウロ

今 羽田空港国際線ラウンジで 7/24 01:30AM発の EMIRATES航空 Dubai行きを待っています 既に日にちが変わりました

Dubaiで同じ Emirates航空に乗り継いで Sao Pauloに向かうのです このルートが日本とサンパウロを結ぶ最短のルートとなりますが 初めて使います

現地には2泊滞在し、 SOLACIという学会に参加し、色々な役割を終え、日曜日 7/28の夕方には成田空港に帰国することになっています。地球の裏側への往復としては最短の旅程でしょうね

この間、 DICOM-XA Viewerプログラムに大きな進展がありました。いくら考えても自分一人では解決できないので、ついに以前コンタクトさせて頂いたその道のプロの方に相談したのです そして、見事に僕の書いたプログラムの中に幾つかのバグを指摘して頂き、その方はきちんとした画像の生成に成功されたのです

頂いたヒントをこの旅行の往復の飛行機の中で解析し、自分のプログラムをきちんとしたものにするつもりです ようやく大きな目標に近づいてきたのです とてもうれしく思います