# fix potential memory leak in MD5Loader.cpp.

- unify formatting in the aforementioned loader.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@875 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2010-12-06 21:31:52 +00:00
parent 86629f5c10
commit e2e5463845
1 changed files with 30 additions and 19 deletions

View File

@ -63,6 +63,7 @@ using namespace Assimp;
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MD5Importer::MD5Importer() MD5Importer::MD5Importer()
: configNoAutoLoad (false) : configNoAutoLoad (false)
, mBuffer()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -79,8 +80,9 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera") if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
return true; return true;
else if (!extension.length() || checkSig) { else if (!extension.length() || checkSig) {
if (!pIOHandler) if (!pIOHandler) {
return true; return true;
}
const char* tokens[] = {"MD5Version"}; const char* tokens[] = {"MD5Version"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
} }
@ -114,7 +116,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false; bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
// remove the file extension // remove the file extension
std::string::size_type pos = pFile.find_last_of('.'); const std::string::size_type pos = pFile.find_last_of('.');
mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1)); mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
@ -125,7 +127,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
else if (configNoAutoLoad || extension == "md5anim") { else if (configNoAutoLoad || extension == "md5anim") {
// determine file extension and process just *one* file // determine file extension and process just *one* file
if (extension.length() == 0) { if (extension.length() == 0) {
/* fixme */ throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
} }
if (extension == "md5anim") { if (extension == "md5anim") {
LoadMD5AnimFile(); LoadMD5AnimFile();
@ -139,29 +141,36 @@ void MD5Importer::InternReadFile( const std::string& pFile,
LoadMD5AnimFile(); LoadMD5AnimFile();
} }
} }
catch ( std::exception&) { catch ( ... ) { // std::exception, Assimp::DeadlyImportError
// XXX use more idiomatic RAII solution
UnloadFileFromMemory(); UnloadFileFromMemory();
throw; throw;
} }
// make sure we have at least one file // make sure we have at least one file
if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
throw DeadlyImportError("Failed to read valid contents from this MD5* file"); throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system // Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f, pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f); 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
// the output scene wouldn't pass the validation without this flag // the output scene wouldn't pass the validation without this flag
if (!bHadMD5Mesh) if (!bHadMD5Mesh) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} }
// clean the instance -- the BaseImporter instance may be reused later.
UnloadFileFromMemory();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load a file into a memory buffer // Load a file into a memory buffer
void MD5Importer::LoadFileIntoMemory (IOStream* file) void MD5Importer::LoadFileIntoMemory (IOStream* file)
{ {
// unload the previous buffer, if any
UnloadFileFromMemory();
ai_assert(NULL != file); ai_assert(NULL != file);
fileSize = (unsigned int)file->FileSize(); fileSize = (unsigned int)file->FileSize();
@ -207,8 +216,9 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){ for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
const aiFace& face = *iter; const aiFace& face = *iter;
for (unsigned int i = 0; i < 3;++i) { for (unsigned int i = 0; i < 3;++i) {
if (face.mIndices[0] >= meshSrc.mVertices.size()) if (face.mIndices[0] >= meshSrc.mVertices.size()) {
throw DeadlyImportError("MD5MESH: Invalid vertex index"); throw DeadlyImportError("MD5MESH: Invalid vertex index");
}
if (abHad[face.mIndices[i]]) { if (abHad[face.mIndices[i]]) {
// generate a new vertex // generate a new vertex
@ -459,8 +469,9 @@ void MD5Importer::LoadMD5MeshFile ()
throw DeadlyImportError("MD5MESH: Invalid weight index"); throw DeadlyImportError("MD5MESH: Invalid weight index");
MD5::WeightDesc& desc = meshSrc.mWeights[w]; MD5::WeightDesc& desc = meshSrc.mWeights[w];
if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON) if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
continue; continue;
}
const float fNewWeight = desc.mWeight / fSum; const float fNewWeight = desc.mWeight / fSum;
@ -478,9 +489,10 @@ void MD5Importer::LoadMD5MeshFile ()
} }
// undo our nice offset tricks ... // undo our nice offset tricks ...
for (unsigned int p = 0; p < mesh->mNumBones;++p) for (unsigned int p = 0; p < mesh->mNumBones;++p) {
mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights; mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
} }
}
delete[] piCount; delete[] piCount;
@ -528,8 +540,6 @@ void MD5Importer::LoadMD5MeshFile ()
mesh->mMaterialIndex = n++; mesh->mMaterialIndex = n++;
} }
#endif #endif
// delete the file again
UnloadFileFromMemory();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -605,15 +615,17 @@ void MD5Importer::LoadMD5AnimFile ()
// translational component // translational component
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (1u << i)) if ((*iter2).iFlags & (1u << i)) {
vKey->mValue[i] = *fpCur++; vKey->mValue[i] = *fpCur++;
}
else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i]; else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
} }
// orientation component // orientation component
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (8u << i)) if ((*iter2).iFlags & (8u << i)) {
vTemp[i] = *fpCur++; vTemp[i] = *fpCur++;
}
else vTemp[i] = pcBaseFrame->vRotationQuat[i]; else vTemp[i] = pcBaseFrame->vRotationQuat[i];
} }
@ -643,8 +655,6 @@ void MD5Importer::LoadMD5AnimFile ()
} }
} }
} }
// delete the file again
UnloadFileFromMemory();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -667,8 +677,9 @@ void MD5Importer::LoadMD5CameraFile ()
// load the camera animation data from the parse tree // load the camera animation data from the parse tree
MD5::MD5CameraParser cameraParser(parser.mSections); MD5::MD5CameraParser cameraParser(parser.mSections);
if (cameraParser.frames.empty()) if (cameraParser.frames.empty()) {
throw DeadlyImportError("MD5CAMERA: No frames parsed"); throw DeadlyImportError("MD5CAMERA: No frames parsed");
}
std::vector<unsigned int>& cuts = cameraParser.cuts; std::vector<unsigned int>& cuts = cameraParser.cuts;
std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames; std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;