Merge branch 'master' into jc3-dnase

pull/3891/head
Kim Kulling 2021-05-12 00:56:46 +02:00 committed by GitHub
commit ad4ca71e4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 180 additions and 128 deletions

View File

@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) { for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
std::string s = mScene->mMaterials[i].mName; std::string s = mScene->mMaterials[i].mName;
for (std::string::iterator it = s.begin(); it != s.end(); ++it) { for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
*it = static_cast<char>(::tolower(*it)); *it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
} }
if (std::string::npos == s.find("default")) continue; if (std::string::npos == s.find("default")) continue;

View File

@ -143,7 +143,13 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void Discreet3DSImporter::InternReadFile(const std::string &pFile, void Discreet3DSImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) { aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE theStream(pIOHandler->Open(pFile, "rb"));
auto theFile = pIOHandler->Open(pFile, "rb");
if (!theFile) {
throw DeadlyImportError("3DS: Could not open ", pFile);
}
StreamReaderLE theStream(theFile);
// We should have at least one chunk // We should have at least one chunk
if (theStream.GetRemainingSize() < 16) { if (theStream.GetRemainingSize() < 16) {

View File

@ -205,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s
} }
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) { static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
return (isalnum(pChar) || (pChar == '+') || (pChar == '/')); return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
} }
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const { void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
@ -268,7 +268,8 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
mXmlParser = new XmlParser(); mXmlParser = new XmlParser();
if (!mXmlParser->parse(file.get())) { if (!mXmlParser->parse(file.get())) {
delete mXmlParser; delete mXmlParser;
throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); mXmlParser = nullptr;
throw DeadlyImportError("Failed to create XML reader for file ", pFile, ".");
} }
// Start reading, search for root tag <amf> // Start reading, search for root tag <amf>

View File

@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() {
ParseLV2MaterialBlock(sMat); ParseLV2MaterialBlock(sMat);
continue; continue;
} }
if( iDepth == 1 ){
// CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51"
LogWarning("Missing closing brace in material list");
--filePtr;
return;
}
} }
AI_ASE_HANDLE_TOP_LEVEL_SECTION(); AI_ASE_HANDLE_TOP_LEVEL_SECTION();
} }

View File

@ -671,7 +671,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
IOStream *stream = pIOHandler->Open(pFile, "rb"); IOStream *stream = pIOHandler->Open(pFile, "rb");
if (nullptr == stream) { if (nullptr == stream) {
return; throw DeadlyImportError("ASSBIN: Could not open ", pFile);
} }
// signature // signature

View File

@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
std::string BVHLoader::GetNextToken() { std::string BVHLoader::GetNextToken() {
// skip any preceding whitespace // skip any preceding whitespace
while (mReader != mBuffer.end()) { while (mReader != mBuffer.end()) {
if (!isspace(*mReader)) if (!isspace((unsigned char)*mReader))
break; break;
// count lines // count lines
@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() {
// collect all chars till the next whitespace. BVH is easy in respect to that. // collect all chars till the next whitespace. BVH is easy in respect to that.
std::string token; std::string token;
while (mReader != mBuffer.end()) { while (mReader != mBuffer.end()) {
if (isspace(*mReader)) if (isspace((unsigned char)*mReader))
break; break;
token.push_back(*mReader); token.push_back(*mReader);

View File

@ -420,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
--s; --s;
} }
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]); curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]);
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]); curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]);
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]); curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]);
curTex->achFormatHint[3] = '\0'; curTex->achFormatHint[3] = '\0';
// tex->mHeight = 0; // tex->mHeight = 0;

View File

@ -137,7 +137,13 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
COB::Scene scene; COB::Scene scene;
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(pIOHandler->Open(pFile, "rb")));
auto file = pIOHandler->Open(pFile, "rb");
if (!file) {
ThrowException("Could not open " + pFile);
}
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
// check header // check header
char head[32]; char head[32];

View File

@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
#if defined(_MSC_VER) #if defined(_MSC_VER)
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') { if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#else #else
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') { if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#endif #endif
--ss.length; --ss.length;
::memmove(ss.data, ss.data + 1, ss.length); ::memmove(ss.data, ss.data + 1, ss.length);

View File

@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
// lower-case shading because Blender (for example) writes "Phong" // lower-case shading because Blender (for example) writes "Phong"
for (size_t i = 0; i < shading.length(); ++i) { for (size_t i = 0; i < shading.length(); ++i) {
shading[i] = static_cast<char>(tolower(shading[i])); shading[i] = static_cast<char>(tolower(static_cast<unsigned char>(shading[i])));
} }
std::string templateName; std::string templateName;
if(shading == "phong") { if(shading == "phong") {

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/HMP/HMPLoader.h" #include "AssetLib/HMP/HMPLoader.h"
#include "AssetLib/MD2/MD2FileData.h" #include "AssetLib/MD2/MD2FileData.h"
#include <assimp/StringUtils.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile,
InternReadFile_HMP7(); InternReadFile_HMP7();
} else { } else {
// Print the magic word to the logger // Print the magic word to the logger
char szBuffer[5]; std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
szBuffer[0] = ((char *)&iMagic)[0];
szBuffer[1] = ((char *)&iMagic)[1];
szBuffer[2] = ((char *)&iMagic)[2];
szBuffer[3] = ((char *)&iMagic)[3];
szBuffer[4] = '\0';
delete[] mBuffer; delete[] mBuffer;
mBuffer = nullptr; mBuffer = nullptr;

View File

@ -859,13 +859,13 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file // Check whether we can read from the file
if (file.get() == nullptr) { if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open IRR file " + pFile); throw DeadlyImportError("Failed to open IRR file ", pFile);
} }
// Construct the irrXML parser // Construct the irrXML parser
XmlParser st; XmlParser st;
if (!st.parse( file.get() )) { if (!st.parse( file.get() )) {
return; throw DeadlyImportError("XML parse error while loading IRR file ", pFile);
} }
pugi::xml_node rootElement = st.getRootNode(); pugi::xml_node rootElement = st.getRootNode();

View File

@ -135,12 +135,12 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file // Check whether we can read from the file
if (file.get() == NULL) if (file.get() == NULL)
throw DeadlyImportError("Failed to open IRRMESH file " + pFile); throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
// Construct the irrXML parser // Construct the irrXML parser
XmlParser parser; XmlParser parser;
if (!parser.parse( file.get() )) { if (!parser.parse( file.get() )) {
return; throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile);
} }
XmlNode root = parser.getRootNode(); XmlNode root = parser.getRootNode();

View File

@ -136,7 +136,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
*/ */
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
unsigned char data[4]; unsigned char data[4];
if (4 != pStream->Read(data, 1, 4)) { if (!pStream || 4 != pStream->Read(data, 1, 4)) {
return false; return false;
} }
return !memcmp(data, "3DMO", 4) /* bin */ return !memcmp(data, "3DMO", 4) /* bin */

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/StringUtils.h>
#include <memory> #include <memory>
@ -148,46 +149,39 @@ void MD2Importer::ValidateHeader( )
if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE && if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE) m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
{ {
char szBuffer[5]; throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ",
szBuffer[0] = ((char*)&m_pcHeader->magic)[0]; ai_str_toprintable((char *)&m_pcHeader->magic, 4));
szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
"magic word found is " + std::string(szBuffer));
} }
// check file format version // check file format version
if (m_pcHeader->version != 8) if (m_pcHeader->version != 8)
ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ..."); ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ...");
// check some values whether they are valid // check some values whether they are valid
if (0 == m_pcHeader->numFrames) if (0 == m_pcHeader->numFrames)
throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0"); throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0");
if (m_pcHeader->offsetEnd > (uint32_t)fileSize) if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
throw DeadlyImportError( "Invalid md2 file: File is too small"); throw DeadlyImportError( "Invalid MD2 file: File is too small");
if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) { if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) {
throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow"); throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow");
} }
if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) { if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) {
throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow"); throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow");
} }
if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) { if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) {
throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow"); throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow");
} }
if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) { if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) {
throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow"); throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow");
} }
if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) { if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) {
throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow"); throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow");
} }
// -1 because Frame already contains one // -1 because Frame already contains one
@ -199,7 +193,7 @@ void MD2Importer::ValidateHeader( )
m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize || m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize ||
m_pcHeader->offsetEnd > fileSize) m_pcHeader->offsetEnd > fileSize)
{ {
throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file"); throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file");
} }
if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS) if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
@ -210,7 +204,7 @@ void MD2Importer::ValidateHeader( )
ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports"); ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports");
if (m_pcHeader->numFrames <= configFrameID ) if (m_pcHeader->numFrames <= configFrameID )
throw DeadlyImportError("The requested frame is not existing the file"); throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -702,7 +702,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
} }
filename = mFile.substr(s), path = mFile.substr(0, s); filename = mFile.substr(s), path = mFile.substr(0, s);
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) { for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
*it = static_cast<char>(tolower(*it)); *it = static_cast<char>(tolower(static_cast<unsigned char>(*it)));
} }
// Load multi-part model file, if necessary // Load multi-part model file, if necessary

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/StringUtils.h>
#include <memory> #include <memory>
@ -143,16 +144,8 @@ void MDCImporter::ValidateHeader() {
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE && if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) { pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
char szBuffer[5]; throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ",
szBuffer[0] = ((char *)&pcHeader->ulIdent)[0]; ai_str_toprintable((char *)&pcHeader->ulIdent, 4));
szBuffer[1] = ((char *)&pcHeader->ulIdent)[1];
szBuffer[2] = ((char *)&pcHeader->ulIdent)[2];
szBuffer[3] = ((char *)&pcHeader->ulIdent)[3];
szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
"magic word found is " +
std::string(szBuffer));
} }
if (pcHeader->ulVersion != AI_MDC_VERSION) { if (pcHeader->ulVersion != AI_MDC_VERSION) {
@ -465,6 +458,13 @@ void MDCImporter::InternReadFile(
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
} }
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
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);
} }
#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER #endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER

View File

@ -252,7 +252,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
} else { } else {
// print the magic word to the log file // print the magic word to the log file
throw DeadlyImportError("Unknown MDL subformat ", pFile, throw DeadlyImportError("Unknown MDL subformat ", pFile,
". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); ". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known");
} }
// 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 convert to internal coordinate system

View File

@ -478,8 +478,7 @@ namespace pmx
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
{ {
std::cerr << "Not Implemented Exception" << std::endl; throw DeadlyImportError("MMD: Soft Body support is not implemented.");
throw DeadlyImportError("MMD: Not Implemented Exception");
} }
void PmxModel::Init() void PmxModel::Init()
@ -517,14 +516,12 @@ namespace pmx
stream->read((char*) magic, sizeof(char) * 4); stream->read((char*) magic, sizeof(char) * 4);
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{ {
std::cerr << "invalid magic number." << std::endl; throw DeadlyImportError("MMD: Invalid magic number.");
throw DeadlyImportError("MMD: invalid magic number.");
} }
stream->read((char*) &version, sizeof(float)); stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f) if (version != 2.0f && version != 2.1f)
{ {
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version));
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version));
} }
this->setting.Read(stream); this->setting.Read(stream);

View File

@ -215,7 +215,12 @@ void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, ai
void MS3DImporter::InternReadFile( const std::string& pFile, void MS3DImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
auto file = pIOHandler->Open(pFile, "rb");
if (!file)
throw DeadlyImportError("MS3D: Could not open ", pFile);
StreamReaderLE stream(file);
// CanRead() should have done this already // CanRead() should have done this already
char head[10]; char head[10];

View File

@ -116,7 +116,13 @@ void NDOImporter::SetupProperties(const Importer* /*pImp*/)
void NDOImporter::InternReadFile( const std::string& pFile, void NDOImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
auto file = pIOHandler->Open( pFile, "rb");
if (!file) {
throw DeadlyImportError("Nendo: Could not open ", pFile);
}
StreamReaderBE reader(file);
// first 9 bytes are nendo file format ("nendo 1.n") // first 9 bytes are nendo file format ("nendo 1.n")
const char* head = (const char*)reader.GetPtr(); const char* head = (const char*)reader.GetPtr();

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
@ -223,6 +224,18 @@ static void propId2StdString(Property *prop, std::string &name, std::string &key
} }
} }
//------------------------------------------------------------------------------------------------
static void logDDLParserMessage (LogSeverity severity, const std::string &rawmsg) {
std::string msg = ai_str_toprintable(rawmsg);
switch (severity) {
case ddl_debug_msg: ASSIMP_LOG_DEBUG(msg); break;
case ddl_info_msg: ASSIMP_LOG_INFO(msg); break;
case ddl_warn_msg: ASSIMP_LOG_WARN(msg); break;
case ddl_error_msg: ASSIMP_LOG_ERROR(msg); break;
default: ASSIMP_LOG_VERBOSE_DEBUG(msg); break;
}
}
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
OpenGEXImporter::VertexContainer::VertexContainer() : OpenGEXImporter::VertexContainer::VertexContainer() :
m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() { m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() {
@ -306,6 +319,7 @@ void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScen
pIOHandler->Close(file); pIOHandler->Close(file);
OpenDDLParser myParser; OpenDDLParser myParser;
myParser.setLogCallback(&logDDLParserMessage);
myParser.setBuffer(&buffer[0], buffer.size()); myParser.setBuffer(&buffer[0], buffer.size());
bool success(myParser.parse()); bool success(myParser.parse());
if (success) { if (success) {

View File

@ -172,7 +172,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
(headerCheck[1] != 'L' && headerCheck[1] != 'l') || (headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y')) { (headerCheck[2] != 'Y' && headerCheck[2] != 'y')) {
streamedBuffer.close(); streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there"); throw DeadlyImportError("Invalid .ply file: Incorrect magic number (expected 'ply' or 'PLY').");
} }
std::vector<char> mBuffer2; std::vector<char> mBuffer2;

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers // internal headers
#include "Q3DLoader.h" #include "Q3DLoader.h"
#include <assimp/StringUtils.h>
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
@ -106,7 +107,12 @@ const aiImporterDesc *Q3DImporter::GetInfo() const {
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void Q3DImporter::InternReadFile(const std::string &pFile, void Q3DImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) { aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
auto file = pIOHandler->Open(pFile, "rb");
if (!file)
throw DeadlyImportError("Quick3D: Could not open ", pFile);
StreamReaderLE stream(file);
// The header is 22 bytes large // The header is 22 bytes large
if (stream.GetRemainingSize() < 22) if (stream.GetRemainingSize() < 22)
@ -115,7 +121,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
// Check the file's signature // Check the file's signature
if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) && if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) { ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8)); throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8));
} }
// Print the file format version // Print the file format version

View File

@ -68,6 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/StringUtils.h>
#include <map> #include <map>
@ -166,14 +167,14 @@ static aiColor3D ReadColor(StreamReaderLE *stream) {
} }
static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) {
char temp[5] = { char temp[4] = {
static_cast<char>((chunk.Tag >> 24) & 0xff), static_cast<char>((chunk.Tag >> 24) & 0xff),
static_cast<char>((chunk.Tag >> 16) & 0xff), static_cast<char>((chunk.Tag >> 16) & 0xff),
static_cast<char>((chunk.Tag >> 8) & 0xff), static_cast<char>((chunk.Tag >> 8) & 0xff),
static_cast<char>(chunk.Tag & 0xff), '\0' static_cast<char>(chunk.Tag & 0xff)
}; };
ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", temp, "' chunk.")); ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."));
} }
// Reads a UTF-16LE string and returns it at UTF-8. // Reads a UTF-16LE string and returns it at UTF-8.
@ -804,7 +805,12 @@ static void ReadScene(SIB *sib, StreamReaderLE *stream) {
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void SIBImporter::InternReadFile(const std::string &pFile, void SIBImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) { aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
auto file = pIOHandler->Open(pFile, "rb");
if (!file)
throw DeadlyImportError("SIB: Could not open ", pFile);
StreamReaderLE stream(file);
// We should have at least one chunk // We should have at least one chunk
if (stream.GetRemainingSize() < 16) if (stream.GetRemainingSize() < 16)

View File

@ -667,8 +667,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
// convert to lower case for easier comparison // convert to lower case for easier comparison
for ( unsigned int c = 0; c < sz.length(); ++c ) { for ( unsigned int c = 0; c < sz.length(); ++c ) {
if ( isalpha( sz[ c ] ) ) { if ( isalpha( (unsigned char) sz[ c ] ) ) {
sz[ c ] = (char) tolower( sz[ c ] ); sz[ c ] = (char) tolower( (unsigned char) sz[ c ] );
} }
} }

View File

@ -1245,13 +1245,13 @@ unsigned int XFileParser::ReadInt() {
} }
// at least one digit expected // at least one digit expected
if (!isdigit(*mP)) if (!isdigit((unsigned char)*mP))
ThrowException("Number expected."); ThrowException("Number expected.");
// read digits // read digits
unsigned int number = 0; unsigned int number = 0;
while (mP < mEnd) { while (mP < mEnd) {
if (!isdigit(*mP)) if (!isdigit((unsigned char)*mP))
break; break;
number = number * 10 + (*mP - 48); number = number * 10 + (*mP - 48);
mP++; mP++;

View File

@ -200,7 +200,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// parse the XML file // parse the XML file
mXmlParser = new XmlParser; mXmlParser = new XmlParser;
if (!mXmlParser->parse(stream.get())) { if (!mXmlParser->parse(stream.get())) {
return; throw DeadlyImportError("XML parse error while loading XGL file ", pFile);
} }
TempScope scope; TempScope scope;

View File

@ -179,7 +179,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
} }
for (size_t i = 0; i < read; ++i) { for (size_t i = 0; i < read; ++i) {
buffer[i] = static_cast<char>(::tolower(buffer[i])); buffer[i] = static_cast<char>(::tolower((unsigned char)buffer[i]));
} }
// It is not a proper handling of unicode files here ... // It is not a proper handling of unicode files here ...
@ -200,7 +200,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
token.clear(); token.clear();
const char *ptr(tokens[i]); const char *ptr(tokens[i]);
for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) { for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) {
token.push_back(static_cast<char>(tolower(*ptr))); token.push_back(static_cast<char>(tolower(static_cast<unsigned char>(*ptr))));
++ptr; ++ptr;
} }
const char *r = strstr(buffer, token.c_str()); const char *r = strstr(buffer, token.c_str());
@ -209,7 +209,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
} }
// We need to make sure that we didn't accidentially identify the end of another token as our token, // We need to make sure that we didn't accidentially identify the end of another token as our token,
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f " // e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) { if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast<unsigned char>(r[-1])))) {
continue; continue;
} }
// We got a match, either we don't care where it is, or it happens to // We got a match, either we don't care where it is, or it happens to

View File

@ -252,7 +252,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) {
std::string ToLower(const std::string &str) { std::string ToLower(const std::string &str) {
std::string out; std::string out;
std::transform(str.begin(), str.end(), std::back_inserter(out), tolower); std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);});
return out; return out;
} }

View File

@ -268,14 +268,14 @@ std::vector<std::string> PlyReader::SplitWords(const std::string &line) {
while ((end = line.find_first_of(" \t\n\v\f\r", start)) != while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
std::string::npos) { std::string::npos) {
const std::string word(line.substr(start, end - start)); const std::string word(line.substr(start, end - start));
if (!std::all_of(word.begin(), word.end(), isspace)) { if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) {
output.push_back(word); output.push_back(word);
} }
start = end + 1; start = end + 1;
} }
const std::string last_word(line.substr(start)); const std::string last_word(line.substr(start));
if (!std::all_of(last_word.begin(), last_word.end(), isspace)) { if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) {
output.push_back(last_word); output.push_back(last_word);
} }
return output; return output;

View File

@ -644,7 +644,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
// Check for invalid characters // Check for invalid characters
for (std::string::size_type index = 0; index < name.size(); ++index) { for (std::string::size_type index = 0; index < name.size(); ++index) {
if (!isalnum(name[index]) && name[index] != '_') if (!IsAlNum(name[index]) && name[index] != '_')
return false; return false;
} }

View File

@ -72,13 +72,15 @@ const char *getTypeToken(Value::ValueType type) {
} }
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
std::stringstream stream; if (callback) {
stream << "Invalid token \"" << *in << "\""
<< " expected \"" << exp << "\"" << std::endl;
std::string full(in); std::string full(in);
std::string part(full.substr(0, 50)); std::string part(full.substr(0, 50));
stream << part; std::stringstream stream;
stream << "Invalid token \"" << *in << "\" "
<< "(expected \"" << exp << "\") "
<< "in: \"" << part << "\"";
callback(ddl_error_msg, stream.str()); callback(ddl_error_msg, stream.str());
}
} }
static bool isIntegerType(Value::ValueType integerType) { static bool isIntegerType(Value::ValueType integerType) {
@ -111,26 +113,8 @@ static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) {
return node; return node;
} }
static void logMessage(LogSeverity severity, const std::string &msg) {
std::string log;
if (ddl_debug_msg == severity) {
log += "Debug:";
} else if (ddl_info_msg == severity) {
log += "Info :";
} else if (ddl_warn_msg == severity) {
log += "Warn :";
} else if (ddl_error_msg == severity) {
log += "Error:";
} else {
log += "None :";
}
log += msg;
std::cout << log;
}
OpenDDLParser::OpenDDLParser() : OpenDDLParser::OpenDDLParser() :
m_logCallback(logMessage), m_logCallback(nullptr),
m_buffer(), m_buffer(),
m_stack(), m_stack(),
m_context(nullptr) { m_context(nullptr) {
@ -138,7 +122,7 @@ OpenDDLParser::OpenDDLParser() :
} }
OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) : OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) :
m_logCallback(&logMessage), m_buffer(), m_context(nullptr) { m_logCallback(nullptr), m_buffer(), m_context(nullptr) {
if (0 != len) { if (0 != len) {
setBuffer(buffer, len); setBuffer(buffer, len);
} }
@ -149,13 +133,8 @@ OpenDDLParser::~OpenDDLParser() {
} }
void OpenDDLParser::setLogCallback(logCallback callback) { void OpenDDLParser::setLogCallback(logCallback callback) {
if (nullptr != callback) { // install user-specific log callback; null = no log callback
// install user-specific log callback
m_logCallback = callback; m_logCallback = callback;
} else {
// install default log callback
m_logCallback = &logMessage;
}
} }
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {

View File

@ -262,7 +262,7 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector<string
inline std::string ai_stdStrToLower(const std::string &str) { inline std::string ai_stdStrToLower(const std::string &str) {
std::string out(str); std::string out(str);
for (size_t i = 0; i < str.size(); ++i) { for (size_t i = 0; i < str.size(); ++i) {
out[i] = (char) tolower(out[i]); out[i] = (char) tolower((unsigned char)out[i]);
} }
return out; return out;
} }

View File

@ -146,8 +146,8 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2) {
#else #else
char c1, c2; char c1, c2;
do { do {
c1 = tolower(*s1++); c1 = tolower((unsigned char)*(s1++));
c2 = tolower(*s2++); c2 = tolower((unsigned char)*(s2++));
} while (c1 && (c1 == c2)); } while (c1 && (c1 == c2));
return c1 - c2; return c1 - c2;
#endif #endif
@ -197,8 +197,8 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
unsigned int p = 0; unsigned int p = 0;
do { do {
if (p++ >= n) return 0; if (p++ >= n) return 0;
c1 = tolower(*s1++); c1 = tolower((unsigned char)*(s1++));
c2 = tolower(*s2++); c2 = tolower((unsigned char)*(s2++));
} while (c1 && (c1 == c2)); } while (c1 && (c1 == c2));
return c1 - c2; return c1 - c2;

View File

@ -157,7 +157,7 @@ AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) {
ss >> result; ss >> result;
for (size_t i = 0; i < result.size(); ++i) { for (size_t i = 0; i < result.size(); ++i) {
result[i] = (char)toupper(result[i]); result[i] = (char)toupper((unsigned char)result[i]);
} }
return result; return result;
@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
return out; return out;
} }
// ---------------------------------------------------------------------------------
/// @brief Make a string printable by replacing all non-printable characters with
/// the specified placeholder character.
/// @param in The incoming string.
/// @param placeholder Placeholder character, default is a question mark.
/// @return The string, with all non-printable characters replaced.
AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') {
std::string out(in);
std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) {
return isprint(c) ? (char)c : placeholder;
});
return out;
}
// ---------------------------------------------------------------------------------
/// @brief Make a string printable by replacing all non-printable characters with
/// the specified placeholder character.
/// @param in The incoming string.
/// @param len The length of the incoming string.
/// @param placeholder Placeholder character, default is a question mark.
/// @return The string, with all non-printable characters replaced. Will return an
/// empty string if in is null or len is <= 0.
AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') {
return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string();
}
#endif // INCLUDED_AI_STRINGUTILS_H #endif // INCLUDED_AI_STRINGUTILS_H

View File

@ -139,7 +139,9 @@ public:
if (parse_result.status == pugi::status_ok) { if (parse_result.status == pugi::status_ok) {
return true; return true;
} else { } else {
ASSIMP_LOG_DEBUG("Error while parse xml."); std::ostringstream oss;
oss << "Error while parsing XML: " << parse_result.description() << " @ " << parse_result.offset;
ASSIMP_LOG_DEBUG(oss.str());
return false; return false;
} }
} }

View File

@ -29,6 +29,7 @@
#include "StringComparison.h" #include "StringComparison.h"
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/StringUtils.h>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <stdint.h> # include <stdint.h>
@ -193,7 +194,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
if ( *in < '0' || *in > '9' ) { if ( *in < '0' || *in > '9' ) {
// The string is known to be bad, so don't risk printing the whole thing. // The string is known to be bad, so don't risk printing the whole thing.
throw ExceptionType("The string \"", std::string(in).substr(0, 100), "\" cannot be converted into a value." ); throw ExceptionType("The string \"", ai_str_toprintable(in, 30), "\" cannot be converted into a value." );
} }
for ( ;; ) { for ( ;; ) {
@ -293,7 +294,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
if (!(c[0] >= '0' && c[0] <= '9') && if (!(c[0] >= '0' && c[0] <= '9') &&
!((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) {
// The string is known to be bad, so don't risk printing the whole thing. // The string is known to be bad, so don't risk printing the whole thing.
throw ExceptionType("Cannot parse string \"", std::string(c).substr(0, 100), throw ExceptionType("Cannot parse string \"", ai_str_toprintable(c, 30),
"\" as a real number: does not start with digit " "\" as a real number: does not start with digit "
"or decimal point followed by digit."); "or decimal point followed by digit.");
} }

View File

@ -272,7 +272,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
szExtFound - 1 - info.cFileName); szExtFound - 1 - info.cFileName);
for (unsigned int i = 0; i < iSizeFound;++i) for (unsigned int i = 0; i < iSizeFound;++i)
info.cFileName[i] = (CHAR)tolower(info.cFileName[i]); info.cFileName[i] = (CHAR)tolower((unsigned char)info.cFileName[i]);
if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize))) if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize)))
{ {
@ -354,7 +354,7 @@ int CMaterialManager::FindValidPath(aiString* p_szString)
for (unsigned int i = 0;;++i) for (unsigned int i = 0;;++i)
{ {
if ('\0' == szTemp[i])break; if ('\0' == szTemp[i])break;
szTemp[i] = (char)tolower(szTemp[i]); szTemp[i] = (char)tolower((unsigned char)szTemp[i]);
} }
if(TryLongerPath(szTemp,p_szString))return 1; if(TryLongerPath(szTemp,p_szString))return 1;