aramis_acg 2011-02-20 00:01:52 +00:00
parent 79eca6196d
commit 94767ecf8c
9 changed files with 80 additions and 41 deletions

View File

@ -328,7 +328,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
if(*((uint16_t*)&data.front()) == 0xFEFF) { if(*((uint16_t*)&data.front()) == 0xFEFF) {
DefaultLogger::get()->debug("Found UTF-16 BOM ..."); DefaultLogger::get()->debug("Found UTF-16 BOM ...");
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)&data.back()+1; const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
char* dstart,*dend; char* dstart,*dend;
std::vector<char> output; std::vector<char> output;
do { do {

View File

@ -236,9 +236,9 @@ struct Mesh
//! \brief Data structure to store all obj-specific model datas //! \brief Data structure to store all obj-specific model datas
struct Model struct Model
{ {
typedef std::map<std::string*, std::vector<unsigned int>* > GroupMap; typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
typedef std::map<std::string*, std::vector<unsigned int>* >::iterator GroupMapIt; typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
typedef std::map<std::string*, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt; typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
//! Model name //! Model name
std::string m_ModelName; std::string m_ModelName;

View File

@ -66,6 +66,8 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
m_uiLine(0), m_uiLine(0),
m_pIO( io ) m_pIO( io )
{ {
memset(m_buffer, BUFFERSIZE, 0);
// Create the model instance to store all the data // Create the model instance to store all the data
m_pModel = new ObjFile::Model(); m_pModel = new ObjFile::Model();
m_pModel->m_ModelName = strModelName; m_pModel->m_ModelName = strModelName;
@ -188,7 +190,7 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
{ {
size_t index = 0; size_t index = 0;
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd ) while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
{ {
pBuffer[index] = *m_DataIt; pBuffer[index] = *m_DataIt;
index++; index++;
@ -262,7 +264,7 @@ void ObjFileParser::getFace()
char *pPtr = m_buffer; char *pPtr = m_buffer;
char *pEnd = &pPtr[BUFFERSIZE]; char *pEnd = &pPtr[BUFFERSIZE];
pPtr = getNextToken<char*>(pPtr, pEnd); pPtr = getNextToken<char*>(pPtr, pEnd);
if (pPtr == '\0') if (pPtr == pEnd || *pPtr == '\0')
return; return;
std::vector<unsigned int> *pIndices = new std::vector<unsigned int>; std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
@ -279,7 +281,7 @@ void ObjFileParser::getFace()
if (*pPtr == '\0') if (*pPtr == '\0')
break; break;
if (*pPtr=='\r') if (*pPtr=='\r' || *pPtr=='\n')
break; break;
if (*pPtr=='/' ) if (*pPtr=='/' )
@ -372,7 +374,7 @@ void ObjFileParser::getMaterialDesc()
return; return;
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd ) while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
++m_DataIt; ++m_DataIt;
// Get name // Get name
@ -406,10 +408,9 @@ void ObjFileParser::getMaterialDesc()
// Get a comment, values will be skipped // Get a comment, values will be skipped
void ObjFileParser::getComment() void ObjFileParser::getComment()
{ {
bool running = true; while (m_DataIt != m_DataItEnd)
while (running)
{ {
if ( '\n' == (*m_DataIt) || m_DataIt == m_DataItEnd ) if ( '\n' == (*m_DataIt))
{ {
++m_DataIt; ++m_DataIt;
break; break;
@ -431,7 +432,7 @@ void ObjFileParser::getMaterialLib()
return; return;
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while (!isNewLine(*m_DataIt)) while (m_DataIt != m_DataItEnd && !isNewLine(*m_DataIt))
m_DataIt++; m_DataIt++;
// Check for existence // Check for existence
@ -465,7 +466,7 @@ void ObjFileParser::getNewMaterial()
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
std::string strMat( pStart, *m_DataIt ); std::string strMat( pStart, *m_DataIt );
while ( isSeparator( *m_DataIt ) ) while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) )
m_DataIt++; m_DataIt++;
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat ); std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
if ( it == m_pModel->m_MaterialMap.end() ) if ( it == m_pModel->m_MaterialMap.end() )
@ -516,7 +517,7 @@ void ObjFileParser::getGroupName()
// Store groupname in group library // Store groupname in group library
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while ( !isSeparator(*m_DataIt) ) while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
m_DataIt++; m_DataIt++;
std::string strGroupName(pStart, &(*m_DataIt)); std::string strGroupName(pStart, &(*m_DataIt));
@ -524,7 +525,7 @@ void ObjFileParser::getGroupName()
if ( m_pModel->m_strActiveGroup != strGroupName ) if ( m_pModel->m_strActiveGroup != strGroupName )
{ {
// Search for already existing entry // Search for already existing entry
ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(&strGroupName); ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName);
// We are mapping groups into the object structure // We are mapping groups into the object structure
createObject( strGroupName ); createObject( strGroupName );
@ -533,7 +534,7 @@ void ObjFileParser::getGroupName()
if (it == m_pModel->m_Groups.end()) if (it == m_pModel->m_Groups.end())
{ {
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
m_pModel->m_Groups[ &strGroupName ] = pFaceIDArray; m_pModel->m_Groups[ strGroupName ] = pFaceIDArray;
m_pModel->m_pGroupFaceIDs = (pFaceIDArray); m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
} }
else else
@ -563,7 +564,7 @@ void ObjFileParser::getObjectName()
if (m_DataIt == m_DataItEnd) if (m_DataIt == m_DataItEnd)
return; return;
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while ( !isSeparator( *m_DataIt ) ) while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) )
++m_DataIt; ++m_DataIt;
std::string strObjectName(pStart, &(*m_DataIt)); std::string strObjectName(pStart, &(*m_DataIt));

View File

@ -147,7 +147,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
uint32_t me = aiHashes[i] = ((MaterialHelper*)pScene->mMaterials[i])->ComputeHash(); uint32_t me = aiHashes[i] = ((MaterialHelper*)pScene->mMaterials[i])->ComputeHash();
for (unsigned int a = 0; a < i;++a) for (unsigned int a = 0; a < i;++a)
{ {
if (me == aiHashes[a]) { if (abReferenced[a] && me == aiHashes[a]) {
++iCnt; ++iCnt;
me = 0; me = 0;
aiMappingTable[i] = aiMappingTable[a]; aiMappingTable[i] = aiMappingTable[a];

View File

@ -47,6 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers of the post-processing framework // internal headers of the post-processing framework
#include "SplitByBoneCountProcess.h" #include "SplitByBoneCountProcess.h"
#include <limits>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -262,7 +264,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
// and copy over the data, generating faces with linear indices along the way // and copy over the data, generating faces with linear indices along the way
newMesh->mFaces = new aiFace[subMeshFaces.size()]; newMesh->mFaces = new aiFace[subMeshFaces.size()];
size_t nvi = 0; // next vertex index size_t nvi = 0; // next vertex index
std::vector<size_t> previousVertexIndices( numSubMeshVertices, SIZE_MAX); // per new vertex: its index in the source mesh std::vector<size_t> previousVertexIndices( numSubMeshVertices, std::numeric_limits<size_t>::max()); // per new vertex: its index in the source mesh
for( size_t a = 0; a < subMeshFaces.size(); ++a ) for( size_t a = 0; a < subMeshFaces.size(); ++a )
{ {
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]]; const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
@ -306,7 +308,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
newMesh->mNumBones = 0; newMesh->mNumBones = 0;
newMesh->mBones = new aiBone*[numBones]; newMesh->mBones = new aiBone*[numBones];
std::vector<size_t> mappedBoneIndex( pMesh->mNumBones, SIZE_MAX); std::vector<size_t> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<size_t>::max());
for( size_t a = 0; a < pMesh->mNumBones; ++a ) for( size_t a = 0; a < pMesh->mNumBones; ++a )
{ {
if( !isBoneUsed[a] ) if( !isBoneUsed[a] )
@ -333,7 +335,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
for( size_t b = 0; b < bonesOnThisVertex.size(); ++b ) for( size_t b = 0; b < bonesOnThisVertex.size(); ++b )
{ {
size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ]; size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
if( newBoneIndex != SIZE_MAX ) if( newBoneIndex != std::numeric_limits<size_t>::max() )
newMesh->mBones[newBoneIndex]->mNumWeights++; newMesh->mBones[newBoneIndex]->mNumWeights++;
} }
} }
@ -359,7 +361,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
for( size_t b = 0; b < bonesOnThisVertex.size(); ++b) for( size_t b = 0; b < bonesOnThisVertex.size(); ++b)
{ {
size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ]; size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
ai_assert( newBoneIndex != SIZE_MAX ); ai_assert( newBoneIndex != std::numeric_limits<size_t>::max() );
aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights; aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
newMesh->mBones[newBoneIndex]->mNumWeights++; newMesh->mBones[newBoneIndex]->mNumWeights++;

View File

@ -101,7 +101,7 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
mImportedMats.clear(); mImportedMats.clear();
// in the hope that binary files will never start with a BOM ... // in the hope that binary files will never start with a BOM ...
mBuffer.resize( fileSize); mBuffer.resize( fileSize + 1);
file->Read( &mBuffer.front(), 1, fileSize); file->Read( &mBuffer.front(), 1, fileSize);
ConvertToUTF8(mBuffer); ConvertToUTF8(mBuffer);

View File

@ -91,7 +91,7 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// set up memory pointers // set up memory pointers
P = &pBuffer.front(); P = &pBuffer.front();
End = P + pBuffer.size(); End = P + pBuffer.size() - 1;
// check header // check header
if( strncmp( P, "xof ", 4) != 0) if( strncmp( P, "xof ", 4) != 0)
@ -180,7 +180,8 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// First find out how much storage we'll need. Count sections. // First find out how much storage we'll need. Count sections.
const char* P1 = P; const char* P1 = P;
unsigned int est_out = 0; unsigned int est_out = 0;
while (P1 < End)
while (P1 + 3 < End)
{ {
// read next offset // read next offset
uint16_t ofs = *((uint16_t*)P1); uint16_t ofs = *((uint16_t*)P1);
@ -199,12 +200,16 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
// and advance to the next offset // and advance to the next offset
P1 += ofs; P1 += ofs;
est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
// this block would continue past the file end, abort
if (P1 > End)
throw DeadlyImportError("X: Unexpected end of file while uncompressing");
} }
// Allocate storage and do the actual uncompressing // Allocate storage and terminating zero and do the actual uncompressing
uncompressed.resize(est_out); uncompressed.resize(est_out + 1);
char* out = &uncompressed.front(); char* out = &uncompressed.front();
while (P < End) while (P + 3 < End)
{ {
uint16_t ofs = *((uint16_t*)P); uint16_t ofs = *((uint16_t*)P);
AI_SWAP2(ofs); AI_SWAP2(ofs);
@ -592,6 +597,9 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh) void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
{ {
readHeadOfDataObject(); readHeadOfDataObject();
if( pMesh->mNumTextures + 1 > AI_MAX_NUMBER_OF_TEXTURECOORDS)
ThrowException( "Too many sets of texture coordinates");
std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++]; std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++];
unsigned int numCoords = ReadInt(); unsigned int numCoords = ReadInt();
@ -609,6 +617,8 @@ void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh) void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
{ {
readHeadOfDataObject(); readHeadOfDataObject();
if( pMesh->mNumColorSets + 1 > AI_MAX_NUMBER_OF_COLOR_SETS)
ThrowException( "Too many colorsets");
std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++]; std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
unsigned int numColors = ReadInt(); unsigned int numColors = ReadInt();
@ -659,7 +669,7 @@ void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
// commented out version check, as version 03.03 exported from blender also has 2 semicolons // commented out version check, as version 03.03 exported from blender also has 2 semicolons
if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2) if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
{ {
if( *P == ';') if(P < End && *P == ';')
++P; ++P;
} }
@ -1043,6 +1053,7 @@ std::string XFileParser::GetNextToken()
// in binary mode it will only return NAME and STRING token // in binary mode it will only return NAME and STRING token
// and (correctly) skip over other tokens. // and (correctly) skip over other tokens.
if( End - P < 2) return s;
unsigned int tok = ReadBinWord(); unsigned int tok = ReadBinWord();
unsigned int len; unsigned int len;
@ -1051,13 +1062,17 @@ std::string XFileParser::GetNextToken()
{ {
case 1: case 1:
// name token // name token
if( End - P < 4) return s;
len = ReadBinDWord(); len = ReadBinDWord();
if( End - P < len) return s;
s = std::string(P, len); s = std::string(P, len);
P += len; P += len;
return s; return s;
case 2: case 2:
// string token // string token
if( End - P < 4) return s;
len = ReadBinDWord(); len = ReadBinDWord();
if( End - P < len) return s;
s = std::string(P, len); s = std::string(P, len);
P += (len + 2); P += (len + 2);
return s; return s;
@ -1070,10 +1085,12 @@ std::string XFileParser::GetNextToken()
P += 16; P += 16;
return "<guid>"; return "<guid>";
case 6: case 6:
if( End - P < 4) return s;
len = ReadBinDWord(); len = ReadBinDWord();
P += (len * 4); P += (len * 4);
return "<int_list>"; return "<int_list>";
case 7: case 7:
if( End - P < 4) return s;
len = ReadBinDWord(); len = ReadBinDWord();
P += (len * mBinaryFloatSize); P += (len * mBinaryFloatSize);
return "<flt_list>"; return "<flt_list>";
@ -1227,6 +1244,7 @@ void XFileParser::ReadUntilEndOfLine()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned short XFileParser::ReadBinWord() unsigned short XFileParser::ReadBinWord()
{ {
assert(End - P >= 2);
const unsigned char* q = (const unsigned char*) P; const unsigned char* q = (const unsigned char*) P;
unsigned short tmp = q[0] | (q[1] << 8); unsigned short tmp = q[0] | (q[1] << 8);
P += 2; P += 2;
@ -1236,6 +1254,7 @@ unsigned short XFileParser::ReadBinWord()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int XFileParser::ReadBinDWord() unsigned int XFileParser::ReadBinDWord()
{ {
assert(End - P >= 4);
const unsigned char* q = (const unsigned char*) P; const unsigned char* q = (const unsigned char*) P;
unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24); unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
P += 4; P += 4;
@ -1247,17 +1266,22 @@ unsigned int XFileParser::ReadInt()
{ {
if( mIsBinaryFormat) if( mIsBinaryFormat)
{ {
if( mBinaryNumCount == 0) if( mBinaryNumCount == 0 && End - P >= 2)
{ {
unsigned short tmp = ReadBinWord(); // 0x06 or 0x03 unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
if( tmp == 0x06) // array of ints follows if( tmp == 0x06 && End - P >= 4) // array of ints follows
mBinaryNumCount = ReadBinDWord(); mBinaryNumCount = ReadBinDWord();
else // single int follows else // single int follows
mBinaryNumCount = 1; mBinaryNumCount = 1;
} }
--mBinaryNumCount; --mBinaryNumCount;
if ( End - P >= 4) {
return ReadBinDWord(); return ReadBinDWord();
} else {
P = End;
return 0;
}
} else } else
{ {
FindNextNoneWhiteSpace(); FindNextNoneWhiteSpace();
@ -1296,10 +1320,10 @@ float XFileParser::ReadFloat()
{ {
if( mIsBinaryFormat) if( mIsBinaryFormat)
{ {
if( mBinaryNumCount == 0) if( mBinaryNumCount == 0 && End - P >= 2)
{ {
unsigned short tmp = ReadBinWord(); // 0x07 or 0x42 unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
if( tmp == 0x07) // array of floats following if( tmp == 0x07 && End - P >= 4) // array of floats following
mBinaryNumCount = ReadBinDWord(); mBinaryNumCount = ReadBinDWord();
else // single float following else // single float following
mBinaryNumCount = 1; mBinaryNumCount = 1;
@ -1308,14 +1332,24 @@ float XFileParser::ReadFloat()
--mBinaryNumCount; --mBinaryNumCount;
if( mBinaryFloatSize == 8) if( mBinaryFloatSize == 8)
{ {
if( End - P >= 8) {
float result = (float) (*(double*) P); float result = (float) (*(double*) P);
P += 8; P += 8;
return result; return result;
} else {
P = End;
return 0;
}
} else } else
{ {
if( End - P >= 4) {
float result = *(float*) P; float result = *(float*) P;
P += 4; P += 4;
return result; return result;
} else {
P = End;
return 0;
}
} }
} }
@ -1323,6 +1357,7 @@ float XFileParser::ReadFloat()
FindNextNoneWhiteSpace(); FindNextNoneWhiteSpace();
// check for various special strings to allow reading files from faulty exporters // check for various special strings to allow reading files from faulty exporters
// I mean you, Blender! // I mean you, Blender!
// Reading is safe because of the terminating zero
if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0) if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
{ {
P += 9; P += 9;

View File

@ -66,7 +66,7 @@ class XFileParser
{ {
public: public:
/** Constructor. Creates a data structure out of the XFile given in the memory block. /** Constructor. Creates a data structure out of the XFile given in the memory block.
* @param pBuffer Memory buffer containing the XFile * @param pBuffer Null-terminated memory buffer containing the XFile
*/ */
XFileParser( const std::vector<char>& pBuffer); XFileParser( const std::vector<char>& pBuffer);

View File

@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "aiTypes.h" #include "aiTypes.h"
#ifdef __cplusplus #ifdef __cplusplus
#include <boost/noncopyable.hpp>
extern "C" { extern "C" {
#endif #endif