| 1288 | } |
| 1289 | |
| 1290 | BlenderImporter::StreamOrError BlenderImporter::ParseMagicToken(const std::string &pFile, IOSystem *pIOHandler) const { |
| 1291 | std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb")); |
| 1292 | if (stream == nullptr) { |
| 1293 | return {{}, {}, "Could not open file for reading"}; |
| 1294 | } |
| 1295 | |
| 1296 | char magic[8] = { 0 }; |
| 1297 | stream->Read(magic, 7, 1); |
| 1298 | if (strcmp(magic, Token) == 0) { |
| 1299 | return {stream, {}, {}}; |
| 1300 | } |
| 1301 | |
| 1302 | // Check for presence of the gzip header. If yes, assume it is a |
| 1303 | // compressed blend file and try uncompressing it, else fail. This is to |
| 1304 | // avoid uncompressing random files which our loader might end up with. |
| 1305 | #ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND |
| 1306 | return {{}, {}, "BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?"}; |
| 1307 | #else |
| 1308 | if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) { |
| 1309 | return {{}, {}, "BLENDER magic bytes are missing, couldn't find GZIP header either"}; |
| 1310 | } |
| 1311 | |
| 1312 | LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file"); |
| 1313 | if (magic[2] != 8) { |
| 1314 | return {{}, {}, "Unsupported GZIP compression method"}; |
| 1315 | } |
| 1316 | |
| 1317 | // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer |
| 1318 | stream->Seek(0L, aiOrigin_SET); |
| 1319 | std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream)); |
| 1320 | |
| 1321 | size_t total = 0; |
| 1322 | Compression compression; |
| 1323 | auto uncompressed = std::make_shared<std::vector<char>>(); |
| 1324 | if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) { |
| 1325 | total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), *uncompressed); |
| 1326 | compression.close(); |
| 1327 | } |
| 1328 | |
| 1329 | // replace the input stream with a memory stream |
| 1330 | stream = std::make_shared<MemoryIOStream>(reinterpret_cast<uint8_t *>(uncompressed->data()), total); |
| 1331 | |
| 1332 | // .. and retry |
| 1333 | stream->Read(magic, 7, 1); |
| 1334 | if (strcmp(magic, Token) == 0) { |
| 1335 | return {stream, uncompressed, {}}; |
| 1336 | } |
| 1337 | return {{}, {}, "Found no BLENDER magic word in decompressed GZIP file"}; |
| 1338 | #endif |
| 1339 | } |
| 1340 | |
| 1341 | #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER |
nothing calls this directly
no test coverage detected