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) {
|
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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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++;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue