Susieプラグイン読み出し-やはりネックは構造体の連結
Susieプラグインを読み出すプログラムは一応テストはうまくいった。しかしやっぱり構造体の連結部分が納得のいく形にはできなかった。
以下はBitmapFileHeaderのbfとBitmapInfoHeaderのpBinfoとピクセルデータのpBmをメモリバッファmem上に連結している部分である。マネージドではMarshal.Copyに頼る方法が妥当という結論に達した。
GCHandle handle = GCHandle.Alloc(bf, GCHandleType.Pinned); try { Marshal.Copy(handle.AddrOfPinnedObject(), mem, 0, Marshal.SizeOf(bf)); } finally { handle.Free(); } Marshal.Copy(pBInfo, mem, Marshal.SizeOf(bf), (int)bf.bfOffBits - Marshal.SizeOf(bf)); Marshal.Copy(pBm, mem, (int)bf.bfOffBits, (int)(bf.bfSize - bf.bfOffBits));
unsafeにしたならば以下のような方法ができる。以下は構造体の代入文とWin32ApiのCopyMemoryを利用している。
unsafe { fixed (byte* fixp = &mem[0]) { *(Win32.BITMAPFILEHEADER*)fixp = bf; Win32.CopyMemory(new IntPtr(fixp + sizeof(Win32.BITMAPFILEHEADER)), pBInfo, (int)bf.bfOffBits - sizeof(Win32.BITMAPFILEHEADER)); Win32.CopyMemory(new IntPtr(fixp + bf.bfOffBits), pBm, (int)(bf.bfSize - bf.bfOffBits)); } }
しっかりと計測したわけじゃないが明らかにunsafeの方がスピードは速い。しかしunsafeブロックをつけるとたったこれだけのコードのためにプロジェクト全体に影響するunsafe有効オプションをチェックしなければいけない。それは私はどうしても避けたいのだ。なぜそこまでアンマネージドを撤廃しようとこだわっているのかって?速度を犠牲にしたとしてもそれに見合うだけのマネージドの価値を私は十分に知っているのだ。嫌というほどに知らされてきたのである。それほどに昔のアンマネージドでしかなかった時代のプログラムのデバッグに・・・多くの大切な生活の貴重な時間を削られた私のせつない過去がそうさせているのである。今日はちょい愚痴っぽいかな。
上記のコードの完成はもう少しかかるのでまた別の画像処理とか寄り道しつつやっていきたいと思う。