LPI-Japan 「Linux標準教科書」の無償提供を開始

PDF形式で無償の「Linux標準教科書」提供開始 Linux初級者が対象:CodeZine
という記事があったので早速ダウンロードしてきました(注:要登録).

まぁ,紹介文にあるようにかなり初心者向けなので,多少知っている人には物足りないかも.
ただ,全256ページで基礎は一通り網羅しているので,学部生のテキストには十分な内容かと.
#こんな教材が無料で手に入るなんて良い時代になったなーと思います.

*******************************

[tmkm-amazon]4861005949[/tmkm-amazon]

がいつの間にか出ていたのでAmazonでポチッと.

[tmkm-amazon]4861004438[/tmkm-amazon]

は初学者向けとして評判が高かったので気になってたんだけどLeopardに
対応してなかったので購入見送ってました.明日には届くはずなので楽しみです!!

*******************************

[tmkm-amazon]0596516134[/tmkm-amazon]

の発売日が以前見たときは9月中旬だった気がするんだけど,10月になってる。。。(※2008年9月18日現在)
記憶ではこの本の発売日が延びるのは今回が初めてではないので,状況が気になるところです.

********************************

dolipoの作者,drikinさんのblogDrift Diary12にこのblogのエントリが紹介されててビックリしました.
ここには特筆すべき記事が皆無なので,リンクからわざわざ来られた方には申し訳ない限りです。。。

あと,久しくweb上に成果物を出していないので,

・マルチタッチテーブル
#相変わらずDiffused Illuminationは日本で流行ってないな。。。

・Gainer C++ライブラリ for Windows
#動作テスト用のセンサが手元に少ししか無いので誰か貸してくれないかな-(苦笑)

あたりを再開したいところです.今週末に少しはできるかな?(多分)

cvReleaseImageの挙動について

OpenCV/videoInput Libraryによるビデオキャプチャのサンプルプログラムについて,
HandyARのデモが動かない問題の原因を発見した – サイScripterの旅立ちにて以下の指摘がありました.

どこのサイトを見ても、どうも怪しいコードしか載っていないように見える。

cvCreateImage後はimageDataにアロケートされているんだから、imageDataに代入しちゃったら解放するアドレスがわからないと思うんだけどなぁ。

でもメモリーリークの警告でないしなぁ・・・

結論から言うとメモリ解放について問題は無いです.ということで,
こちらとしても,「怪しいコードと断定」されるのも癪なので,
なぜ問題無いかについて少し書いてみます.

まず,cvReleaseImageの内部で何をやっているかというと,
確保したイメージ領域の解放のためにcvReleaseDataをコールしています.
cxarray.cppのcvReleaseData関数の中身を以下に示します.

[cpp]
// Deallocates array’s data
CV_IMPL void
cvReleaseData( CvArr* arr )
{
CV_FUNCNAME( “cvReleaseData” );

__BEGIN__;

if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
{
CvMat* mat = (CvMat*)arr;
cvDecRefData( mat );
}
else if( CV_IS_IMAGE_HDR( arr ))
{
IplImage* img = (IplImage*)arr;

if( !CvIPL.deallocate )
{
char* ptr = img->imageDataOrigin;
img->imageData = img->imageDataOrigin = 0;
cvFree( &ptr );
}
else
{
CvIPL.deallocate( img, IPL_IMAGE_DATA );
}
}
else
{
CV_ERROR( CV_StsBadArg, “unrecognized or unsupported array type” );
}

__END__;
}
[/cpp]

その中で,
[cpp]
if( !CvIPL.deallocate )
{
char* ptr = img->imageDataOrigin;
img->imageData = img->imageDataOrigin = 0;
cvFree( &ptr );
}
[/cpp]
という部分からわかるように実際に解放するメモリ領域の先頭アドレスとして指定されるのは
img->imageDataOriginであることがわかると思います.

では,img->imageDataOriginって何?という話になるので,
IplImage構造体について一度確認してみましょう.
cxtypes.hのIplImage構造体の定義を以下に示します.

[cpp]
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* ignored by OpenCV */
int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */
char colorModel[4]; /* ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 – interleaved color channels, 1 – separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 – top-left origin,
1 – bottom-left origin (Windows bitmaps style) */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead */
int width; /* image width in pixels */
int height; /* image height in pixels */
struct _IplROI *roi;/* image ROI. if NULL, the whole image is selected */
struct _IplImage *maskROI; /* must be NULL */
void *imageId; /* ditto */
struct _IplTileInfo *tileInfo; /* ditto */
int imageSize; /* image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* pointer to aligned image data */
int widthStep; /* size of aligned image row in bytes */
int BorderMode[4]; /* ignored by OpenCV */
int BorderConst[4]; /* ditto */
char *imageDataOrigin; /* pointer to very origin of image data
(not necessarily aligned) –
needed for correct deallocation */
}
IplImage;
[/cpp]

コメントにもありますが,imageDataOriginは,cvCreateImageで確保したイメージ領域を解放する
ことを保証するために用意されていて,実際にcvCreateImage関数の内部で
呼ばれるcvCreateData関数の中で,イメージ領域の割り当て時に
イメージ領域の先頭アドレスはimageDataとimageDataOriginの両方に格納されます.
cvarray.cppのcvCreateData関数の一部を以下に示します.

[cpp]
if( !CvIPL.allocateData )
{
CV_CALL( img->imageData = img->imageDataOrigin =
(char*)cvAlloc( (size_t)img->imageSize ));
}
[/cpp]

ということで,imageDataが変更されても,imageDataOriginにイメージ領域の先頭アドレスが
格納されているので,cvReleaseImageできちんと解放されることがおわかりいただけると思います.

そんなわけで,OpenCVの内部でどうなっているかを把握した上で書いている点ご理解ください.
※誤解を生まないようVI.getPixelsで取得したイメージデータをmemcpy使ってコピーすれば
 いいんでしょうけど,ループ中にメモリコピーを行うと速度が落ちそうなので,ポインタの変更で済ませちゃってます.

#まぁ,指摘通り,C,C++がある程度わかる人には一見危なそうに見えるのは事実なんですが,
#このようにきちんと内部動作まで解説するとそれなりに大変で,初心者がそれを読むと挫折しそうなので
#今のところ説明を省いています.その辺のバランスって難しいですよね。。。
#何か良い案があれば教えてください.

ターニングポイント的なもの(違)

同期曰く,年齢を重ねていくうちに運動しても体重が減りにくくなるターニングポイント的なものを
感じる瞬間があるらしい.今のところそんな予兆は全くないけど恐ろしい.
自分の場合,学生時よりも運動量は減って,食べる量は増えた気がするんだけど,
体重は平行線なので,むしろ,原理が説明できない自分の身体が不気味でしょうがない(苦笑)

とか書くと,いろんな方面から反感を買いそうだけど,「食べ過ぎて運動しなかったら太る」という
ごく当たり前の法則が成り立たないのはなんだか気持ち悪い.摂取したエネルギーは何処へ(遠い目)

というか,どんだけ燃費が悪いんだ。。。orz
#逆に原理がわかればビジネスになりそうだけど.

***********

[tmkm-amazon]4797346809[/tmkm-amazon]

も時間を見つけてちょこちょこ読んでますが,
Objective-Cは特殊な言語? – @ITはさらっと読めそうなので,後で読んどこう.
それにしてもなかなかObjective-C独特の記述に慣れないな。。。

CocoaアプリやiPod touchアプリを開発するなら必須の知識らしいので,
なんとか身につけたい言語ではあるんだけど.