Merge branch 'new-file-detection' of https://github.com/krishty/assimp into krishty-new-file-detection

pull/4342/head
Kim Kulling 2022-01-16 20:41:24 +01:00
commit 05746acb07
51 changed files with 273 additions and 669 deletions

View File

@ -111,20 +111,9 @@ Discreet3DSImporter::~Discreet3DSImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
std::string extension = GetExtension(pFile); static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
if (extension == "3ds" || extension == "prj") { return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]);
return true;
}
if (!extension.length() || checkSig) {
uint16_t token[3];
token[0] = 0x4d4d;
token[1] = 0x3dc2;
//token[2] = 0x3daa;
return CheckMagicToken(pIOHandler, pFile, token, 2, 0, 2);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -90,24 +90,12 @@ D3MFImporter::~D3MFImporter() {
// empty // empty
} }
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const { bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension(GetExtension(filename)); if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
if (extension == desc.mFileExtensions) { return false;
return true;
}
if (!extension.length() || checkSig) {
if (nullptr == pIOHandler) {
return false;
}
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
D3MFOpcPackage opcPackage(pIOHandler, filename);
return opcPackage.validate();
} }
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
return false; return opcPackage.validate();
} }
void D3MFImporter::SetupProperties(const Importer*) { void D3MFImporter::SetupProperties(const Importer*) {

View File

@ -152,18 +152,9 @@ AC3DImporter::~AC3DImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
std::string extension = GetExtension(pFile); static const uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
// fixme: are acc and ac3d *really* used? Some sources say they are
if (extension == "ac" || extension == "ac3d" || extension == "acc") {
return true;
}
if (!extension.length() || checkSig) {
uint32_t token = AI_MAKE_MAGIC("AC3D");
return CheckMagicToken(pIOHandler, pFile, &token, 1, 0);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -503,19 +503,9 @@ void AMFImporter::ParseNode_Metadata(XmlNode &node) {
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
} }
bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const { bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*pCheckSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "amf") {
return true;
}
if (extension.empty() || pCheckSig) {
static const char * const tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
const aiImporterDesc *AMFImporter::GetInfo() const { const aiImporterDesc *AMFImporter::GetInfo() const {

View File

@ -95,19 +95,9 @@ ASEImporter::~ASEImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const { bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// check file extension static const char *tokens[] = { "*3dsmax_asciiexport" };
const std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "ase" || extension == "ask") {
return true;
}
if ((!extension.length() || cs) && pIOHandler) {
static const char * const tokens[] = { "*3dsmax_asciiexport" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -92,19 +92,8 @@ B3DImporter::~B3DImporter() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool B3DImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool B3DImporter::CanRead(const std::string & /*pFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return false;
size_t pos = pFile.find_last_of('.');
if (pos == string::npos) {
return false;
}
string ext = pFile.substr(pos + 1);
if (ext.size() != 3) {
return false;
}
return (ext[0] == 'b' || ext[0] == 'B') && (ext[1] == '3') && (ext[2] == 'd' || ext[2] == 'D');
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -92,18 +92,9 @@ BVHLoader::~BVHLoader() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const { bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// check file extension static const char *tokens[] = { "HIERARCHY" };
const std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "bvh")
return true;
if ((!extension.length() || cs) && pIOHandler) {
static const char * const tokens[] = { "HIERARCHY" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -118,18 +118,9 @@ static const char * const TokensForSearch[] = { "blender" };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string &extension = GetExtension(pFile); // note: this won't catch compressed files
if (extension == "blend") { return SearchFileHeaderForToken(pIOHandler, pFile, TokensForSearch, AI_COUNT_OF(TokensForSearch));
return true;
}
if ((!extension.length() || checkSig) && pIOHandler) {
// note: this won't catch compressed files
return SearchFileHeaderForToken(pIOHandler, pFile, TokensForSearch, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -106,14 +106,19 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { C4DImporter::C4DImporter()
const std::string& extension = GetExtension(pFile); : BaseImporter() {
if (extension == "c4d") { // empty
return true; }
} else if ((!extension.length() || checkSig) && pIOHandler) {
// TODO
}
// ------------------------------------------------------------------------------------------------
C4DImporter::~C4DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& /*pFile*/, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
// TODO
return false; return false;
} }

View File

@ -103,17 +103,9 @@ COBImporter::~COBImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string &extension = GetExtension(pFile); static const char *tokens[] = { "Caligary" };
if (extension == "cob" || extension == "scn" || extension == "COB" || extension == "SCN") { return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
return true;
}
else if ((!extension.length() || checkSig) && pIOHandler) {
static const char * const tokens[] = { "Caligary" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -90,19 +90,10 @@ CSMImporter::~CSMImporter()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{ {
// check file extension static const char* tokens[] = {"$Filename"};
const std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
if( extension == "csm")
return true;
if ((checkSig || !extension.length()) && pIOHandler) {
static const char * const tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -116,37 +116,15 @@ ColladaLoader::~ColladaLoader() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// check file extension // Look for a DAE file inside, but don't extract it
const std::string extension = GetExtension(pFile); ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
const bool readSig = checkSig && (pIOHandler != nullptr); if (zip_archive.isOpen()) {
if (!readSig) { return !ColladaParser::ReadZaeManifest(zip_archive).empty();
if (extension == "dae" || extension == "zae") {
return true;
}
} else {
// Look for a DAE file inside, but don't extract it
ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
if (zip_archive.isOpen()) {
return !ColladaParser::ReadZaeManifest(zip_archive).empty();
}
} }
// XML - too generic, we need to open the file and search for typical keywords static const char *tokens[] = { "<collada" };
if (extension == "xml" || !extension.length() || checkSig) { return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
// If CanRead() is called in order to check whether we
// support a specific file extension in general pIOHandler
// might be nullptr and it's our duty to return true here.
if (nullptr == pIOHandler) {
return true;
}
static const char * const tokens[] = {
"<collada"
};
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -123,18 +123,9 @@ DXFImporter::~DXFImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool checkSig ) const { bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
const std::string& extension = GetExtension( filename ); static const char *tokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
if ( extension == desc.mFileExtensions ) { return SearchFileHeaderForToken(pIOHandler, filename, tokens, AI_COUNT_OF(tokens), 32);
return true;
}
if ( extension.empty() || checkSig ) {
static const char * const pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -100,18 +100,10 @@ FBXImporter::~FBXImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
const std::string &extension = GetExtension(pFile); // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
if (extension == std::string(desc.mFileExtensions)) { static const char *tokens[] = { "fbx" };
return true; return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
else if ((!extension.length() || checkSig) && pIOHandler) {
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
static const char * const tokens[] = { "fbx" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -84,20 +84,13 @@ HMPImporter::~HMPImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const { bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = {
if (extension == "hmp") AI_HMP_MAGIC_NUMBER_LE_4,
return true; AI_HMP_MAGIC_NUMBER_LE_5,
AI_HMP_MAGIC_NUMBER_LE_7
// if check for extension is not enough, check for the magic tokens };
if (!extension.length() || cs) { return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
uint32_t tokens[3];
tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
return CheckMagicToken(pIOHandler, pFile, tokens, 3, 0);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -129,18 +129,12 @@ IFCImporter::~IFCImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string &extension = GetExtension(pFile); // note: this is the common identification for STEP-encoded files, so
if (extension == "ifc" || extension == "ifczip") { // it is only unambiguous as long as we don't support any further
return true; // file formats with STEP as their encoding.
} else if ((!extension.length() || checkSig) && pIOHandler) { static const char *tokens[] = { "ISO-10303-21" };
// note: this is the common identification for STEP-encoded files, so return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
// it is only unambiguous as long as we don't support any further
// file formats with STEP as their encoding.
static const char * const tokens[] = { "ISO-10303-21" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -94,23 +94,9 @@ IRRImporter::~IRRImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool IRRImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool IRRImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "irr_scene" };
if (extension == "irr") { return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
return true;
} else if (extension == "xml" || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be nullptr and it's our duty to return true here.
*/
if (nullptr == pIOHandler) {
return true;
}
static const char * const tokens[] = { "irr_scene" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -85,26 +83,14 @@ IRRMeshImporter::~IRRMeshImporter() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
/* NOTE: A simple check for the file extension is not enough /* NOTE: A simple check for the file extension is not enough
* here. Irrmesh and irr are easy, but xml is too generic * here. Irrmesh and irr are easy, but xml is too generic
* and could be collada, too. So we need to open the file and * and could be collada, too. So we need to open the file and
* search for typical tokens. * search for typical tokens.
*/ */
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "irrmesh" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "irrmesh")
return true;
else if (extension == "xml" || checkSig) {
/* If CanRead() is called to check whether the loader
* supports a specific file extension in general we
* must return true here.
*/
if (!pIOHandler) return true;
static const char * const tokens[] = { "irrmesh" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -105,21 +105,13 @@ LWOImporter::~LWOImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const { bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(file); static const uint32_t tokens[] = {
if (extension == "lwo" || extension == "lxo") { AI_LWO_FOURCC_LWOB,
return true; AI_LWO_FOURCC_LWO2,
} AI_LWO_FOURCC_LXOB
};
// if check for extension is not enough, check for the magic tokens return CheckMagicToken(pIOHandler, file, tokens, AI_COUNT_OF(tokens), 8);
if (!extension.length() || checkSig) {
uint32_t tokens[3];
tokens[0] = AI_LWO_FOURCC_LWOB;
tokens[1] = AI_LWO_FOURCC_LWO2;
tokens[2] = AI_LWO_FOURCC_LXOB;
return CheckMagicToken(pIOHandler, file, tokens, 3, 8);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -147,20 +147,12 @@ LWSImporter::~LWSImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = {
if (extension == "lws" || extension == "mot") { AI_MAKE_MAGIC("LWSC"),
return true; AI_MAKE_MAGIC("LWMO")
} };
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
// if check for extension is not enough, check for the magic tokens LWSC and LWMO
if (!extension.length() || checkSig) {
uint32_t tokens[2];
tokens[0] = AI_MAKE_MAGIC("LWSC");
tokens[1] = AI_MAKE_MAGIC("LWMO");
return CheckMagicToken(pIOHandler, pFile, tokens, 2);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -111,34 +111,21 @@ M3DImporter::M3DImporter() :
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is a binary or ASCII Model 3D file. // Returns true, if file is a binary or ASCII Model 3D file.
bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); /*
* don't use CheckMagicToken because that checks with swapped bytes too, leading to false
if (extension == "m3d" * positives. This magic is not uint32_t, but char[4], so memcmp is the best way
|| extension == "a3d" */
) std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
return true; unsigned char data[4];
else if (!extension.length() || checkSig) { if (4 != pStream->Read(data, 1, 4)) {
if (!pIOHandler) { return false;
return true;
}
/*
* don't use CheckMagicToken because that checks with swapped bytes too, leading to false
* positives. This magic is not uint32_t, but char[4], so memcmp is the best way
const char* tokens[] = {"3DMO", "3dmo"};
return CheckMagicToken(pIOHandler,pFile,tokens,2,0,4);
*/
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
unsigned char data[4];
if (!pStream || 4 != pStream->Read(data, 1, 4)) {
return false;
}
return !memcmp(data, "3DMO", 4) /* bin */
|| !memcmp(data, "3dmo", 4) /* ASCII */
;
} }
return false; return !memcmp(data, "3DMO", 4) /* bin */
#ifdef M3D_ASCII
|| !memcmp(data, "3dmo", 4) /* ASCII */
#endif
;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -107,19 +107,10 @@ MD2Importer::~MD2Importer()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{ {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = { AI_MD2_MAGIC_NUMBER_LE };
if (extension == "md2") return CheckMagicToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
return true;
// if check for extension is not enough, check for the magic tokens
if (!extension.length() || checkSig) {
uint32_t tokens[1];
tokens[0] = AI_MD2_MAGIC_NUMBER_LE;
return CheckMagicToken(pIOHandler,pFile,tokens,1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -349,18 +349,9 @@ MD3Importer::~MD3Importer() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD3Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool MD3Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = { AI_MD3_MAGIC_NUMBER_LE };
if (extension == "md3") return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
return true;
// if check for extension is not enough, check for the magic tokens
if (!extension.length() || checkSig) {
uint32_t tokens[1];
tokens[0] = AI_MD3_MAGIC_NUMBER_LE;
return CheckMagicToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -100,20 +100,9 @@ MD5Importer::~MD5Importer() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "MD5Version" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
return true;
else if (!extension.length() || checkSig) {
if (!pIOHandler) {
return true;
}
static const char * const tokens[] = { "MD5Version" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -111,19 +111,9 @@ MDCImporter::~MDCImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = { AI_MDC_MAGIC_NUMBER_LE };
if (extension == "mdc") { return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
return true;
}
// if check for extension is not enough, check for the magic tokens
if (!extension.length() || checkSig) {
uint32_t tokens[1];
tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
return CheckMagicToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -104,23 +104,18 @@ MDLImporter::~MDLImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const uint32_t tokens[] = {
AI_MDL_MAGIC_NUMBER_LE_HL2a,
// if check for extension is not enough, check for the magic tokens AI_MDL_MAGIC_NUMBER_LE_HL2b,
if (extension == "mdl" || !extension.length() || checkSig) { AI_MDL_MAGIC_NUMBER_LE_GS7,
uint32_t tokens[8]; AI_MDL_MAGIC_NUMBER_LE_GS5b,
tokens[0] = AI_MDL_MAGIC_NUMBER_LE_HL2a; AI_MDL_MAGIC_NUMBER_LE_GS5a,
tokens[1] = AI_MDL_MAGIC_NUMBER_LE_HL2b; AI_MDL_MAGIC_NUMBER_LE_GS4,
tokens[2] = AI_MDL_MAGIC_NUMBER_LE_GS7; AI_MDL_MAGIC_NUMBER_LE_GS3,
tokens[3] = AI_MDL_MAGIC_NUMBER_LE_GS5b; AI_MDL_MAGIC_NUMBER_LE
tokens[4] = AI_MDL_MAGIC_NUMBER_LE_GS5a; };
tokens[5] = AI_MDL_MAGIC_NUMBER_LE_GS4; return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
tokens[6] = AI_MDL_MAGIC_NUMBER_LE_GS3;
tokens[7] = AI_MDL_MAGIC_NUMBER_LE;
return CheckMagicToken(pIOHandler, pFile, tokens, 8, 0);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -89,14 +89,9 @@ MMDImporter::~MMDImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is an pmx file. // Returns true, if file is an pmx file.
bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const { bool /*checkSig*/) const {
if (!checkSig) { static const char *tokens[] = { "PMX " };
return SimpleExtensionCheck(pFile, "pmx"); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} else {
// Check file Header
static const char * const pTokens[] = { "PMX " };
return SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -88,26 +88,12 @@ MS3DImporter::MS3DImporter()
// Destructor, private as well // Destructor, private as well
MS3DImporter::~MS3DImporter() MS3DImporter::~MS3DImporter()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{ {
// first call - simple extension check static const char* tokens[] = { "MS3D000000" };
const std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
if (extension == "ms3d") {
return true;
}
// second call - check for magic identifiers
else if (!extension.length() || checkSig) {
if (!pIOHandler) {
return true;
}
static const char * const tokens[] = {"MS3D000000"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -82,19 +80,10 @@ NDOImporter::~NDOImporter()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{ {
// check file extension static const char* tokens[] = {"nendo"};
const std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens),5);
if( extension == "ndo")
return true;
if ((checkSig || !extension.length()) && pIOHandler) {
static const char * const tokens[] = {"nendo"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -83,8 +83,8 @@ NFFImporter::~NFFImporter() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool NFFImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool NFFImporter::CanRead(const std::string & /*pFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "nff", "enff"); return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -83,19 +83,10 @@ OFFImporter::~OFFImporter()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{ {
const std::string extension = GetExtension(pFile); static const char* tokens[] = { "off" };
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens),3);
if (extension == "off")
return true;
else if (!extension.length() || checkSig)
{
if (!pIOHandler)return true;
static const char * const tokens[] = {"off"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,3);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -87,16 +87,10 @@ ObjFileImporter::~ObjFileImporter() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is an obj file. // Returns true if file is an obj file.
bool ObjFileImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool ObjFileImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
if (!checkSig) { static const char *tokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
//Check File Extension return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens), 200, false, true);
return SimpleExtensionCheck(pFile, "obj");
} else {
// Check file Header
static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9, 200, false, true);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -73,14 +73,13 @@ void OgreImporter::SetupProperties(const Importer *pImp) {
m_detectTextureTypeFromFilename = pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false); m_detectTextureTypeFromFilename = pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false);
} }
bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const { bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool /*checkSig*/) const {
if (!checkSig) {
return EndsWith(pFile, ".mesh.xml", false) || EndsWith(pFile, ".mesh", false);
}
if (EndsWith(pFile, ".mesh.xml", false)) { if (EndsWith(pFile, ".mesh.xml", false)) {
static const char * const tokens[] = { "<mesh>" }; static const char *tokens[] = { "<mesh>" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} else {
/// @todo Read and validate first header chunk?
return false;
} }
/// @todo Read and validate first header chunk? /// @todo Read and validate first header chunk?

View File

@ -290,16 +290,9 @@ OpenGEXImporter::~OpenGEXImporter() {
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const { bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
bool canRead(false); static const char *tokens[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
if (!checkSig) { return SearchFileHeaderForToken(pIOHandler, file, tokens, AI_COUNT_OF(tokens));
canRead = SimpleExtensionCheck(file, "ogex");
} else {
static const char * const token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
canRead = SearchFileHeaderForToken(pIOHandler, file, token, 4);
}
return canRead;
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------

View File

@ -100,24 +100,9 @@ PLYImporter::~PLYImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "ply" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "ply") {
return true;
}
if (!extension.length() || checkSig) {
if (!pIOHandler) {
return true;
}
static const char * const tokens[] = {
"ply"
};
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -156,12 +156,8 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the loader can read this. // Returns true if the loader can read this.
bool Q3BSPFileImporter::CanRead(const std::string &rFile, IOSystem * /*pIOHandler*/, bool checkSig) const { bool Q3BSPFileImporter::CanRead(const std::string &/*rFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
if (!checkSig) {
return SimpleExtensionCheck(rFile, "pk3", "bsp");
}
return false; return false;
} }

View File

@ -84,18 +84,9 @@ Q3DImporter::~Q3DImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool Q3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool Q3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "quick3Do", "quick3Ds" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "q3s" || extension == "q3o")
return true;
else if (!extension.length() || checkSig) {
if (!pIOHandler)
return true;
static const char * const tokens[] = { "quick3Do", "quick3Ds" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 2);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -84,8 +84,8 @@ RAWImporter::~RAWImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool RAWImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool RAWImporter::CanRead(const std::string & /*pFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "raw"); return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -217,8 +217,8 @@ SIBImporter::~SIBImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool SIBImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool SIBImporter::CanRead(const std::string & /*pFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "sib"); return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -101,9 +101,9 @@ SMDImporter::~SMDImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool SMDImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool) const { bool SMDImporter::CanRead( const std::string& /*pFile*/, IOSystem* /*pIOHandler*/, bool) const {
// fixme: auto format detection // fixme: auto format detection
return SimpleExtensionCheck(pFile,"smd","vta"); return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -140,22 +140,9 @@ STLImporter::~STLImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool STLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool STLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
const std::string extension = GetExtension(pFile); static const char *tokens[] = { "STL", "solid" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "stl") {
return true;
}
if (!extension.length() || checkSig) {
if (!pIOHandler) {
return true;
}
static const char * const tokens[] = { "STL", "solid" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 2);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -81,27 +81,9 @@ TerragenImporter::~TerragenImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// check file extension static const char *tokens[] = { "terragen" };
std::string extension = GetExtension(pFile); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
if (extension == "ter")
return true;
if (!extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be nullptr and it's our duty to return true here.
*/
if (!pIOHandler) {
return true;
}
static const char * const tokens[] = { "terragen" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -176,8 +176,8 @@ UnrealImporter::~UnrealImporter() {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool UnrealImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool UnrealImporter::CanRead(const std::string & /*pFile*/, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "3d", "uc"); return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -88,17 +88,9 @@ XFileImporter::~XFileImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const {
std::string extension = GetExtension(pFile); static const uint32_t token[] = { AI_MAKE_MAGIC("xof ") };
if(extension == "x") { return CheckMagicToken(pIOHandler,pFile,token,AI_COUNT_OF(token));
return true;
}
if (!extension.length() || checkSig) {
uint32_t token[1];
token[0] = AI_MAKE_MAGIC("xof ");
return CheckMagicToken(pIOHandler,pFile,token,1,0);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -104,25 +104,9 @@ XGLImporter::~XGLImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const { bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
/* NOTE: A simple check for the file extension is not enough static const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
* here. XGL and ZGL are ok, but xml is too generic return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
* and might be collada as well. So open the file and
* look for typical signal tokens.
*/
const std::string extension = GetExtension(pFile);
if (extension == "xgl" || extension == "zgl") {
return true;
}
if (extension == "xml" || checkSig) {
ai_assert(pIOHandler != nullptr);
static const char * const tokens[] = { "<world>", "<World>", "<WORLD>" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 3);
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -93,24 +93,14 @@ const aiImporterDesc *glTFImporter::GetInfo() const {
} }
bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const { bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const {
const std::string &extension = GetExtension(pFile); glTF::Asset asset(pIOHandler);
try {
if (extension != "gltf" && extension != "glb") { asset.Load(pFile, GetExtension(pFile) == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '1';
} catch (...) {
return false; return false;
} }
if (pIOHandler) {
glTF::Asset asset(pIOHandler);
try {
asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '1';
} catch (...) {
return false;
}
}
return false;
} }
inline void SetMaterialColorProperty(std::vector<int> &embeddedTexIdxs, Asset & /*r*/, glTF::TexProperty prop, aiMaterial *mat, inline void SetMaterialColorProperty(std::vector<int> &embeddedTexIdxs, Asset & /*r*/, glTF::TexProperty prop, aiMaterial *mat,

View File

@ -111,18 +111,15 @@ const aiImporterDesc *glTF2Importer::GetInfo() const {
return &desc; return &desc;
} }
bool glTF2Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig ) const { bool glTF2Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const {
const std::string &extension = GetExtension(pFile); try {
glTF2::Asset asset(pIOHandler);
if (!checkSig && (extension != "gltf") && (extension != "glb")) asset.Load(pFile, GetExtension(pFile) == "glb");
return false; std::string version = asset.asset.version;
return !version.empty() && version[0] == '2';
if (pIOHandler) { } catch(...) {
glTF2::Asset asset(pIOHandler); return false;
return asset.CanRead(pFile, extension == "glb"); }
}
return false;
} }
static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) { static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) {

View File

@ -156,8 +156,8 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem *pIOHandler, /*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem *pIOHandler,
const std::string &pFile, const std::string &pFile,
const char * const *tokens, const char **tokens,
unsigned int numTokens, std::size_t numTokens,
unsigned int searchBytes /* = 200 */, unsigned int searchBytes /* = 200 */,
bool tokensSol /* false */, bool tokensSol /* false */,
bool noAlphaBeforeTokens /* false */) { bool noAlphaBeforeTokens /* false */) {
@ -225,32 +225,6 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
return false; return false;
} }
// ------------------------------------------------------------------------------------------------
// Simple check for file extension
/*static*/ bool BaseImporter::SimpleExtensionCheck(const std::string &pFile,
const char *ext0,
const char *ext1,
const char *ext2) {
std::string::size_type pos = pFile.find_last_of('.');
// no file extension - can't read
if (pos == std::string::npos)
return false;
const char *ext_real = &pFile[pos + 1];
if (!ASSIMP_stricmp(ext_real, ext0))
return true;
// check for other, optional, file extensions
if (ext1 && !ASSIMP_stricmp(ext_real, ext1))
return true;
if (ext2 && !ASSIMP_stricmp(ext_real, ext2))
return true;
return false;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get file extension from path // Get file extension from path
std::string BaseImporter::GetExtension(const std::string &file) { std::string BaseImporter::GetExtension(const std::string &file) {
@ -271,7 +245,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check for magic bytes at the beginning of the file. // Check for magic bytes at the beginning of the file.
/* static */ bool BaseImporter::CheckMagicToken(IOSystem *pIOHandler, const std::string &pFile, /* static */ bool BaseImporter::CheckMagicToken(IOSystem *pIOHandler, const std::string &pFile,
const void *_magic, unsigned int num, unsigned int offset, unsigned int size) { const void *_magic, std::size_t num, unsigned int offset, unsigned int size) {
ai_assert(size <= 16); ai_assert(size <= 16);
ai_assert(_magic); ai_assert(_magic);

View File

@ -617,29 +617,71 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
profiler->BeginRegion("total"); profiler->BeginRegion("total");
} }
// Find an worker class which can handle the file // Find an worker class which can handle the file extension.
BaseImporter* imp = nullptr; // Multiple importers may be able to handle the same extension (.xml!); gather them all.
SetPropertyInteger("importerIndex", -1); SetPropertyInteger("importerIndex", -1);
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { struct ImporterAndIndex {
BaseImporter * importer;
unsigned int index;
};
std::vector<ImporterAndIndex> possibleImporters;
for (unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
// Every importer has a list of supported extensions.
std::set<std::string> extensions;
pimpl->mImporter[a]->GetExtensionList(extensions);
// CAUTION: Do not just search for the extension!
// GetExtension() returns the part after the *last* dot, but some extensions have dots
// inside them, e.g. ogre.mesh.xml. Compare the entire end of the string.
for (std::set<std::string>::const_iterator it = extensions.cbegin(); it != extensions.cend(); ++it) {
// Yay for C++<20 not having std::string::ends_with()
std::string extension = "." + *it;
if (extension.length() <= pFile.length()) {
// Possible optimization: Fetch the lowercase filename!
if (0 == ASSIMP_stricmp(pFile.c_str() + pFile.length() - extension.length(), extension.c_str())) {
ImporterAndIndex candidate = { pimpl->mImporter[a], a };
possibleImporters.push_back(candidate);
break;
}
}
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
imp = pimpl->mImporter[a];
SetPropertyInteger("importerIndex", a);
break;
} }
}
// If just one importer supports this extension, pick it and close the case.
BaseImporter* imp = nullptr;
if (1 == possibleImporters.size()) {
imp = possibleImporters[0].importer;
SetPropertyInteger("importerIndex", possibleImporters[0].index);
}
// If multiple importers claim this file extension, ask them to look at the actual file data to decide.
// This can happen e.g. with XML (COLLADA vs. Irrlicht).
else {
for (std::vector<ImporterAndIndex>::const_iterator it = possibleImporters.begin(); it < possibleImporters.end(); ++it) {
BaseImporter & importer = *it->importer;
ASSIMP_LOG_INFO("Found a possible importer: " + std::string(importer.GetInfo()->mName) + "; trying signature-based detection");
if (importer.CanRead( pFile, pimpl->mIOHandler, true)) {
imp = &importer;
SetPropertyInteger("importerIndex", it->index);
break;
}
}
} }
if (!imp) { if (!imp) {
// not so bad yet ... try format auto detection. // not so bad yet ... try format auto detection.
const std::string::size_type s = pFile.find_last_of('.'); ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
if (s != std::string::npos) { for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
ASSIMP_LOG_INFO("File extension not known, trying signature-based detection"); if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { imp = pimpl->mImporter[a];
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { SetPropertyInteger("importerIndex", a);
imp = pimpl->mImporter[a]; break;
SetPropertyInteger("importerIndex", a);
break;
}
} }
} }
// Put a proper error message if no suitable importer was found // Put a proper error message if no suitable importer was found

View File

@ -95,20 +95,15 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* *
* The implementation should be as quick as possible. A check for * The implementation is expected to perform a full check of the file
* the file extension is enough. If no suitable loader is found with * structure, possibly searching the first bytes of the file for magic
* this strategy, CanRead() is called again, the 'checkSig' parameter * identifiers or keywords.
* set to true this time. Now the implementation is expected to
* perform a full check of the file structure, possibly searching the
* first bytes of the file for magic identifiers or keywords.
* *
* @param pFile Path and file name of the file to be examined. * @param pFile Path and file name of the file to be examined.
* @param pIOHandler The IO handler to use for accessing any file. * @param pIOHandler The IO handler to use for accessing any file.
* @param checkSig Set to true if this method is called a second time. * @param checkSig Legacy; do not use.
* This time, the implementation may take more time to examine the * @return true if the class can read this file, false if not or if
* contents of the file to be loaded for magic bytes, keywords, etc * unsure.
* to be able to load files with unknown/not existent file extensions.
* @return true if the class can read this file, false if not.
*/ */
virtual bool CanRead( virtual bool CanRead(
const std::string &pFile, const std::string &pFile,
@ -259,26 +254,12 @@ public: // static utilities
static bool SearchFileHeaderForToken( static bool SearchFileHeaderForToken(
IOSystem *pIOSystem, IOSystem *pIOSystem,
const std::string &file, const std::string &file,
const char * const *tokens, const char **tokens,
unsigned int numTokens, std::size_t numTokens,
unsigned int searchBytes = 200, unsigned int searchBytes = 200,
bool tokensSol = false, bool tokensSol = false,
bool noAlphaBeforeTokens = false); bool noAlphaBeforeTokens = false);
// -------------------------------------------------------------------
/** @brief Check whether a file has a specific file extension
* @param pFile Input file
* @param ext0 Extension to check for. Lowercase characters only, no dot!
* @param ext1 Optional second extension
* @param ext2 Optional third extension
* @note Case-insensitive
*/
static bool SimpleExtensionCheck(
const std::string &pFile,
const char *ext0,
const char *ext1 = nullptr,
const char *ext2 = nullptr);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Extract file extension from a string /** @brief Extract file extension from a string
* @param pFile Input file * @param pFile Input file
@ -305,7 +286,7 @@ public: // static utilities
IOSystem *pIOHandler, IOSystem *pIOHandler,
const std::string &pFile, const std::string &pFile,
const void *magic, const void *magic,
unsigned int num, std::size_t num,
unsigned int offset = 0, unsigned int offset = 0,
unsigned int size = 4); unsigned int size = 4);

View File

@ -331,4 +331,6 @@ static const ai_real ai_epsilon = (ai_real)0.00001;
#define AI_DEBUG_INVALIDATE_PTR(x) #define AI_DEBUG_INVALIDATE_PTR(x)
#endif #endif
#define AI_COUNT_OF(X) (sizeof(X) / sizeof((X)[0]))
#endif // !! AI_DEFINES_H_INC #endif // !! AI_DEFINES_H_INC