3MF
メモリのオーバーフロー
次の様なコードで,実行時にエラー.
i_DIB DIB_FlipVertical (const i_DIB& dib_)
{
i_DIB dib = dib_ ;
if (dib_.GetWidth () == 0) { return dib ; }
if (dib_.GetHeight() == 0) { return dib ; }
u_32* bits = (u_32*)dib.GetP_Bits() ;
for ( int y=0 ; y<dib.GetHeight()/2 ; y++) {
for (int x=0 ; x<dib.GetWidth() ; x++) {
u_32 sPos = x+dib.GetWidth()*( y) ;
u_32 dPos = x+dib.GetWidth()*(dib.GetHeight()- y) ;
u_32 tmp = *(bits+(dPos)) ;
*(bits+(dPos)) = *(bits+(sPos)) ;
*(bits+(sPos)) = tmp ;
}
}
return dib ;
}
原因は最初の dPos が画像の範囲を超えていること.これはすぐにわかったが,
デバッガで追いかけてもこのループは何もなかったかの様に通り,この関数を抜ける時にエラーとなる.
たまたまと言うこともあると思うが,MFC の配列を使用していればアクセスした段階で ASSERT されるのでは?
i_dib_f.hxx
AMF texture
AMF を調べていて,テクスチャ部分の変換テスト.
次の様なコードで,それぞれの色の成分の画像が出来ることを確認.
inline AMF_Texture AMF_texture_To (const Xml_E& tex_e)
{
AMF_Texture tex ;
if (tex_e.GetName() != AMF_texture) { return tex ; }
tex.ID = tex_e.GetAttribute(AMF_id) ;
tex.Width = ::ttou4 ( tex_e.GetAttribute(AMF_width)) ;
tex.Height = ::ttou4 ( tex_e.GetAttribute(AMF_height)) ;
tex.Texture = ::base64_decode(::To_v_char(tex_e.GetText())) ;
{
i_DIB dib ;
dib.Create(tex.Width,tex.Height) ;
for ( long y=0 ; y<dib.GetHeight() ; y++) {
for (long x=0 ; x<dib.GetWidth () ; x++) {
u_32 pc = *(dib.GetP_Pixel(x,y)) ;
u_32 argb = pc ;
if (unsigned(x+y*dib.GetWidth()) < tex.Texture.size()) {
u__8 c = tex.Texture[x+y*dib.GetWidth()] ;
argb = 0xff000000 + (c<<16) + (c<<8) + (c) ;
}
u_32* bits = (u_32*)dib.GetP_Bits() ;
*(bits+(x+y*dib.GetWidth())) = argb ;
}
}
tstring dibName ;
{
// …
dibName = outPath + _T("\\") + tex.ID + _T("_") + ::To_tstring(Count) + _T(".dib") ;
}
::HBITMAP_To(::ToHBITMAP(dib),dibName.c_str()) ;
}
return tex ;
}
1.5 M 位の bmp をテクスチャとして求め,それを数100個?生成していて,メモリ不足.
原因はすぐわかったが,この上のコードでもある様に ToHBITMAP() で求めた HBITMAP を DeleteObject してない.
次の様にする必要がある.
HBITMAP hBMP = ::ToHBITMAP(dib) ;
::HBITMAP_To(hBMP,dibName.c_str()) ;
::DeleteObject(hBMP) ;
幸いこの関係のコードを書いたのが今年になってからだったので,利用している部分は限定的.
検索をかけて変更が必要な所は 10 箇所程度?
多くは,デバッグ版でのみ実行されるコード.
AMF_Texture のデータメンバを protected に.
v_char AMF_Texture::GetTexture() を用意して,それを利用する様に変更すると,デバッグ版で遅い.
ここでの対応はすぐわかったが,この類のコードが相当ありそう.
参照の関係の理解が不十分なので,もう少し調べる必要あり.