git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@903 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
79eca6196d
commit
94767ecf8c
|
@ -328,7 +328,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
|||
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
||||
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;
|
||||
std::vector<char> output;
|
||||
do {
|
||||
|
|
|
@ -236,9 +236,9 @@ struct Mesh
|
|||
//! \brief Data structure to store all obj-specific model datas
|
||||
struct Model
|
||||
{
|
||||
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>* >::const_iterator ConstGroupMapIt;
|
||||
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>* >::const_iterator ConstGroupMapIt;
|
||||
|
||||
//! Model name
|
||||
std::string m_ModelName;
|
||||
|
|
|
@ -66,6 +66,8 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
|
|||
m_uiLine(0),
|
||||
m_pIO( io )
|
||||
{
|
||||
memset(m_buffer, BUFFERSIZE, 0);
|
||||
|
||||
// Create the model instance to store all the data
|
||||
m_pModel = new ObjFile::Model();
|
||||
m_pModel->m_ModelName = strModelName;
|
||||
|
@ -188,7 +190,7 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
|||
{
|
||||
size_t index = 0;
|
||||
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;
|
||||
index++;
|
||||
|
@ -262,7 +264,7 @@ void ObjFileParser::getFace()
|
|||
char *pPtr = m_buffer;
|
||||
char *pEnd = &pPtr[BUFFERSIZE];
|
||||
pPtr = getNextToken<char*>(pPtr, pEnd);
|
||||
if (pPtr == '\0')
|
||||
if (pPtr == pEnd || *pPtr == '\0')
|
||||
return;
|
||||
|
||||
std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
|
||||
|
@ -279,7 +281,7 @@ void ObjFileParser::getFace()
|
|||
if (*pPtr == '\0')
|
||||
break;
|
||||
|
||||
if (*pPtr=='\r')
|
||||
if (*pPtr=='\r' || *pPtr=='\n')
|
||||
break;
|
||||
|
||||
if (*pPtr=='/' )
|
||||
|
@ -372,7 +374,7 @@ void ObjFileParser::getMaterialDesc()
|
|||
return;
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
|
||||
while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
|
||||
++m_DataIt;
|
||||
|
||||
// Get name
|
||||
|
@ -406,10 +408,9 @@ void ObjFileParser::getMaterialDesc()
|
|||
// Get a comment, values will be skipped
|
||||
void ObjFileParser::getComment()
|
||||
{
|
||||
bool running = true;
|
||||
while (running)
|
||||
while (m_DataIt != m_DataItEnd)
|
||||
{
|
||||
if ( '\n' == (*m_DataIt) || m_DataIt == m_DataItEnd )
|
||||
if ( '\n' == (*m_DataIt))
|
||||
{
|
||||
++m_DataIt;
|
||||
break;
|
||||
|
@ -431,7 +432,7 @@ void ObjFileParser::getMaterialLib()
|
|||
return;
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
while (!isNewLine(*m_DataIt))
|
||||
while (m_DataIt != m_DataItEnd && !isNewLine(*m_DataIt))
|
||||
m_DataIt++;
|
||||
|
||||
// Check for existence
|
||||
|
@ -465,7 +466,7 @@ void ObjFileParser::getNewMaterial()
|
|||
|
||||
char *pStart = &(*m_DataIt);
|
||||
std::string strMat( pStart, *m_DataIt );
|
||||
while ( isSeparator( *m_DataIt ) )
|
||||
while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) )
|
||||
m_DataIt++;
|
||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
||||
if ( it == m_pModel->m_MaterialMap.end() )
|
||||
|
@ -516,7 +517,7 @@ void ObjFileParser::getGroupName()
|
|||
|
||||
// Store groupname in group library
|
||||
char *pStart = &(*m_DataIt);
|
||||
while ( !isSeparator(*m_DataIt) )
|
||||
while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
|
||||
m_DataIt++;
|
||||
std::string strGroupName(pStart, &(*m_DataIt));
|
||||
|
||||
|
@ -524,7 +525,7 @@ void ObjFileParser::getGroupName()
|
|||
if ( m_pModel->m_strActiveGroup != strGroupName )
|
||||
{
|
||||
// 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
|
||||
createObject( strGroupName );
|
||||
|
@ -533,7 +534,7 @@ void ObjFileParser::getGroupName()
|
|||
if (it == m_pModel->m_Groups.end())
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
@ -563,7 +564,7 @@ void ObjFileParser::getObjectName()
|
|||
if (m_DataIt == m_DataItEnd)
|
||||
return;
|
||||
char *pStart = &(*m_DataIt);
|
||||
while ( !isSeparator( *m_DataIt ) )
|
||||
while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) )
|
||||
++m_DataIt;
|
||||
|
||||
std::string strObjectName(pStart, &(*m_DataIt));
|
||||
|
|
|
@ -147,7 +147,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
|||
uint32_t me = aiHashes[i] = ((MaterialHelper*)pScene->mMaterials[i])->ComputeHash();
|
||||
for (unsigned int a = 0; a < i;++a)
|
||||
{
|
||||
if (me == aiHashes[a]) {
|
||||
if (abReferenced[a] && me == aiHashes[a]) {
|
||||
++iCnt;
|
||||
me = 0;
|
||||
aiMappingTable[i] = aiMappingTable[a];
|
||||
|
|
|
@ -47,6 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// internal headers of the post-processing framework
|
||||
#include "SplitByBoneCountProcess.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
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
|
||||
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
||||
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 )
|
||||
{
|
||||
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
||||
|
@ -306,7 +308,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
|||
newMesh->mNumBones = 0;
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
size_t newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
|
||||
if( newBoneIndex != SIZE_MAX )
|
||||
if( newBoneIndex != std::numeric_limits<size_t>::max() )
|
||||
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)
|
||||
{
|
||||
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;
|
||||
newMesh->mBones[newBoneIndex]->mNumWeights++;
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|||
mImportedMats.clear();
|
||||
|
||||
// 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);
|
||||
ConvertToUTF8(mBuffer);
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|||
|
||||
// set up memory pointers
|
||||
P = &pBuffer.front();
|
||||
End = P + pBuffer.size();
|
||||
End = P + pBuffer.size() - 1;
|
||||
|
||||
// check header
|
||||
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.
|
||||
const char* P1 = P;
|
||||
unsigned int est_out = 0;
|
||||
while (P1 < End)
|
||||
|
||||
while (P1 + 3 < End)
|
||||
{
|
||||
// read next offset
|
||||
uint16_t ofs = *((uint16_t*)P1);
|
||||
|
@ -199,12 +200,16 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|||
// and advance to the next offset
|
||||
P1 += ofs;
|
||||
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
|
||||
uncompressed.resize(est_out);
|
||||
// Allocate storage and terminating zero and do the actual uncompressing
|
||||
uncompressed.resize(est_out + 1);
|
||||
char* out = &uncompressed.front();
|
||||
while (P < End)
|
||||
while (P + 3 < End)
|
||||
{
|
||||
uint16_t ofs = *((uint16_t*)P);
|
||||
AI_SWAP2(ofs);
|
||||
|
@ -592,6 +597,9 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
|
|||
void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
|
||||
{
|
||||
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++];
|
||||
|
||||
unsigned int numCoords = ReadInt();
|
||||
|
@ -609,6 +617,8 @@ void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
|
|||
void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
|
||||
{
|
||||
readHeadOfDataObject();
|
||||
if( pMesh->mNumColorSets + 1 > AI_MAX_NUMBER_OF_COLOR_SETS)
|
||||
ThrowException( "Too many colorsets");
|
||||
std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
|
||||
|
||||
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
|
||||
if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
|
||||
{
|
||||
if( *P == ';')
|
||||
if(P < End && *P == ';')
|
||||
++P;
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1053,7 @@ std::string XFileParser::GetNextToken()
|
|||
// in binary mode it will only return NAME and STRING token
|
||||
// and (correctly) skip over other tokens.
|
||||
|
||||
if( End - P < 2) return s;
|
||||
unsigned int tok = ReadBinWord();
|
||||
unsigned int len;
|
||||
|
||||
|
@ -1051,13 +1062,17 @@ std::string XFileParser::GetNextToken()
|
|||
{
|
||||
case 1:
|
||||
// name token
|
||||
if( End - P < 4) return s;
|
||||
len = ReadBinDWord();
|
||||
if( End - P < len) return s;
|
||||
s = std::string(P, len);
|
||||
P += len;
|
||||
return s;
|
||||
case 2:
|
||||
// string token
|
||||
if( End - P < 4) return s;
|
||||
len = ReadBinDWord();
|
||||
if( End - P < len) return s;
|
||||
s = std::string(P, len);
|
||||
P += (len + 2);
|
||||
return s;
|
||||
|
@ -1070,10 +1085,12 @@ std::string XFileParser::GetNextToken()
|
|||
P += 16;
|
||||
return "<guid>";
|
||||
case 6:
|
||||
if( End - P < 4) return s;
|
||||
len = ReadBinDWord();
|
||||
P += (len * 4);
|
||||
return "<int_list>";
|
||||
case 7:
|
||||
if( End - P < 4) return s;
|
||||
len = ReadBinDWord();
|
||||
P += (len * mBinaryFloatSize);
|
||||
return "<flt_list>";
|
||||
|
@ -1227,6 +1244,7 @@ void XFileParser::ReadUntilEndOfLine()
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned short XFileParser::ReadBinWord()
|
||||
{
|
||||
assert(End - P >= 2);
|
||||
const unsigned char* q = (const unsigned char*) P;
|
||||
unsigned short tmp = q[0] | (q[1] << 8);
|
||||
P += 2;
|
||||
|
@ -1236,6 +1254,7 @@ unsigned short XFileParser::ReadBinWord()
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int XFileParser::ReadBinDWord()
|
||||
{
|
||||
assert(End - P >= 4);
|
||||
const unsigned char* q = (const unsigned char*) P;
|
||||
unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
|
||||
P += 4;
|
||||
|
@ -1247,17 +1266,22 @@ unsigned int XFileParser::ReadInt()
|
|||
{
|
||||
if( mIsBinaryFormat)
|
||||
{
|
||||
if( mBinaryNumCount == 0)
|
||||
if( mBinaryNumCount == 0 && End - P >= 2)
|
||||
{
|
||||
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();
|
||||
else // single int follows
|
||||
mBinaryNumCount = 1;
|
||||
}
|
||||
|
||||
--mBinaryNumCount;
|
||||
if ( End - P >= 4) {
|
||||
return ReadBinDWord();
|
||||
} else {
|
||||
P = End;
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
FindNextNoneWhiteSpace();
|
||||
|
@ -1296,10 +1320,10 @@ float XFileParser::ReadFloat()
|
|||
{
|
||||
if( mIsBinaryFormat)
|
||||
{
|
||||
if( mBinaryNumCount == 0)
|
||||
if( mBinaryNumCount == 0 && End - P >= 2)
|
||||
{
|
||||
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();
|
||||
else // single float following
|
||||
mBinaryNumCount = 1;
|
||||
|
@ -1308,14 +1332,24 @@ float XFileParser::ReadFloat()
|
|||
--mBinaryNumCount;
|
||||
if( mBinaryFloatSize == 8)
|
||||
{
|
||||
if( End - P >= 8) {
|
||||
float result = (float) (*(double*) P);
|
||||
P += 8;
|
||||
return result;
|
||||
} else {
|
||||
P = End;
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if( End - P >= 4) {
|
||||
float result = *(float*) P;
|
||||
P += 4;
|
||||
return result;
|
||||
} else {
|
||||
P = End;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1323,6 +1357,7 @@ float XFileParser::ReadFloat()
|
|||
FindNextNoneWhiteSpace();
|
||||
// check for various special strings to allow reading files from faulty exporters
|
||||
// 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)
|
||||
{
|
||||
P += 9;
|
||||
|
|
|
@ -66,7 +66,7 @@ class XFileParser
|
|||
{
|
||||
public:
|
||||
/** 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);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "aiTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <boost/noncopyable.hpp>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue